- From: François REMY <francois.remy.dev@outlook.com>
- Date: Tue, 8 Oct 2013 12:12:38 +0200
- To: "Tab Atkins Jr." <jackalmage@gmail.com>, "www-style list" <www-style@w3.org>
I support the change. However, given IE just shipped and will probably not ship in a while, I believe doing a usage counter round may actually be useful - we have time. Maintaining an incompatible behavior between browsers is probably the only way to make sure the usage doesn't grow over time, though. That being said, it still exposes browser rounding when computing whether the sum is equal or greater than 1. It is likely than to defeat rounding issues UA will want to accept a certain "snapping-to-1" tolerance. -----Message d'origine----- From: Tab Atkins Jr. Sent: Tuesday, October 8, 2013 1:10 AM To: www-style list Subject: [css-flexbox] Fixing a mistake with flex-grow betwen 0 and 1 I've been thinking about this lately, and I think I made a mistake in how I specified the behavior of 'flex-grow' values greater than 0 but less than 1. The current behavior isn't compatible with animation, and a small fix would also enable a useful behavior for authors. I believe this mistake can be safely corrected with insignificant, if any, compat problems. # Problem Right now, the spec treats flex-grow values between 0 and 1 the same as values 1+ - they get normalized into a share of the free space, and then space gets distributed. This means that *any* non-zero value, even something as tiny as .0001, will cause the element to flex and fill its container. This is troublesome when you try to animate between 0 and a non-zero value, because a lone flexible element stays container-filling until the final moment when its flex-grow reaches 0, at which point it's suddenly completely inflexible and flips to its normal size. Because this isn't really "transitioning", I even explicitly disallow animating between 0 and non-zero. This is annoying, because if there are *two* flexible items on the line, then transitioning one of them to 0 *does* work properly - the item gradually shrinks to its hypothetical size, as expected. This problem only occurs when there's only a single flexible item on the line, which is annoying and confusing to authors. As well, this is discontinuous behavior that exposes UA rounding behavior, which is something we try to avoid whenever possible. # Suggested Solution Lightly reinterpret flex to be literally a fraction of the free space, with the usual "1 = 100%" conversion. If the sum of the flexes on a flex line is greater than 1, normalize appropriately, but if not, leave the numbers alone. In specific edits, this would just be a change in the <http://dev.w3.org/csswg/css-flexbox/#resolve-flexible-lengths> section - insert a step 2.5 that checks if the free space is positive and the sum of the flex-grows are <1, and if so, sets all the flex items to their hypothetical main size + the corresponding fraction of the free space, then exits the algorithm. # Benefits This change would allow 'flex' to be animated between 0 and non-zero values in all cases. If there's a single flexible item, as its flex-grow drops below 1, it'll start using less than all of the free space, gradually shrinking to its hypothetical main size, exactly what you get from an inflexible item. This gives us precisely what we want, and eliminates the discontinuity. This has real worth. Without this, you can't easily do flexible accordions, where when everything is closed they pack toward flex-start, but when a section is expanded it fills the available space. Another unexpected benefit of this is that it allows a reasonable, though not perfect, solution to the "items on the last flex-line are way too big" problem, where the last line in a multi-line flexbox sometimes has 1 or 2 items which stretch to fill the entire line, ending up ridiculously larger than all the other items in the flexbox. This can be fixed by, rather than specifying everything with a flex of "1", instead specifying a flex of the maximum fraction of the line you want something to fill, approximately. For example, if your flexbox will typically have 4-6 items per line, just set each to "flex: .25", and the ones on the final line will be reasonably sized, while the rest of the lines are unaffected (the sum of flexes will be 1 to 1.5, which means they get normalized as usual and soak up all the free space). This requires you to guess how many items will fit on a line, which isn't ideal, but is often good enough. I plan to address this more thoroughly in Flexbox 2. # Compat Risk I expect the compat risk for this change to be insignificant, if not nonexistent. This only affects items with a flex value >0 and <1, which should be rare in the first place - the spec only uses integer values, every tutorial I've seen avoids values in that range, and I've never seen real code try to use values in that range either. Further, it only affects these items if the sum of the flexes on the line is less than 1. Two items both with "flex: .5;" will continue to work as normal, for example. I suspect anything hitting this case to be *very* rare. I could use a use-counter to try and track this stuff, but I fear that a 12- to 18-week delay for full results might result in a growth of the usage of this case, as unprefixed Flexbox impls move into the public web. I believe it's safe to make this change as long as we do so quickly. Thoughts? ~TJ
Received on Tuesday, 8 October 2013 10:12:53 UTC