- From: Tab Atkins Jr. <jackalmage@gmail.com>
- Date: Fri, 4 Jun 2010 15:14:20 -0700
- To: www-style list <www-style@w3.org>
Alex brought up a good point regarding box-pack in another thread. According to the current draft, box-pack applies at the very end of computation, after all descendants have reached their maximum size. In my proposal, it does the opposite due to me misreading this section. The equivalent of box-pack - putting padding on the parent - occurs before the children are allowed to flex. This is somewhat inconvenient in some cases when a flexible length on a child doesn't have a preferred size, and so doesn't claim any of the free space when the parent is trying to flex its padding. I immediately considered just reversing my first and second distribution rounds to achieve the same effect. However, this produces some inconsistences when you next flexboxes. If a flexbox is, itself, a child of a flexbox, then its padding *must* resolve its flexes before its children do, as it's part of the flex distribution on its own parent. Examples would probably help. Assume this markup using the current flexbox draft: <div id=a display:box; box-pack:center;> <div id=b display:box; box-pack:center; box-flex:1;> <div id=c box-flex:1;>foo</div> </div> </div> And the intended equivalent in my proposal: <div id=a display:flex; width:1000px; padding: 0 1fl;> <div id=b display:flex; width:1fla; padding: 0 1fl;> <div id=c width: 1fla;>foo</div> </div> </div> (1) In the current flexbox draft, you get a display like: ┏━━━━━━━━━━━━━━━━━━━┓ ┃┏━━━━━━━━━━━━━━━━━┓┃ ┃┃┏━━━━━━━━━━━━━━━┓┃┃ ┃┃┃foo ┃┃┃ ┃┃┗━━━━━━━━━━━━━━━┛┃┃ ┃┗━━━━━━━━━━━━━━━━━┛┃ ┗━━━━━━━━━━━━━━━━━━━┛ It does this by following these steps: 1. #b determines its preferred width 1a. It asks its children for their preferred width. #c's preferred width is the width of "foo". 2. #b then takes up all the space in #a. 3. There is no free space left in #a, so the box-pack has no effect. 4. #c determines its preferred width. This is the width of "foo". 5. #c then takes up all the space in #b. 6. There is no free space left in #b, so the box-pack has no effect. (2) In my proposal, on the other hand, you'll see this rendering: ┏━━━━━━━━━━━━━━━━━━━┓ ┃ ┏━━━━━┓ ┃ ┃ ┃┏━━━┓┃ ┃ ┃ ┃┃foo┃┃ ┃ ┃ ┃┗━━━┛┃ ┃ ┃ ┗━━━━━┛ ┃ ┗━━━━━━━━━━━━━━━━━━━┛ It does this by following these steps: 1. #a asks its children for their preferred widths. 1a. #b's preferred width is the width of its content, #c. 1b. #c's preferred width is the width of its content, "foo". 2. #a then figures out how much free space it has and divvies that up between its two paddings. 3. There is no free space left for #b's padding or width to eat up. 4. There is no free space left for #c's width to eat up. (3) If I reverse the first and second distribution rounds of my proposal, though, then it produces: ┏━━━━━━━━━━━━━━━━━━━┓ ┃┏━━━━━━━━━━━━━━━━━┓┃ ┃┃ ┏━━━━━━━┓ ┃┃ ┃┃ ┃foo ┃ ┃┃ ┃┃ ┗━━━━━━━┛ ┃┃ ┃┗━━━━━━━━━━━━━━━━━┛┃ ┗━━━━━━━━━━━━━━━━━━━┛ Because: 1. #a first lays out its children 1a. #b asks its children (#c) for their preferred width (the width of "foo"). 1b. #a then collects the free space (100px - "foo".width, or, um, 12 spaces in the ascii art) and distributes it to #b's padding and width 2. There's no free space left over in #a, so no space gets given to the padding. 3. #b then lays out its children. #a has a preferred width of 3 spaces, #b has free space of 7, so #a eats all of the space for its width. This is sorta crazy. The order which padding on the flexbox is processed depends on whether the grandparent understands flexes or not. So, I can't do (3), it's crazy and difficult to predict. The question is, which is most useful, (1) or (2)? In (1) you can simulate (2) by providing a max-width, while (2) can simulate (1) by providing a min-width. Alternately, (2) can simulate (1) through a separate property that takes a flex length and evaluates it a separate distribution round between the current round 2 and 3, so you wouldn't be forced to handle the lengths differently based on whether the grandparent is a flexbox. You'd then write it like: <div id=a display:flex; width:1000px; flex-pack: 1fl 1fl;> <div id=b display:flex; width:1fla; flex-pack: 1fl 1fl;> <div id=c width: 1fla;>foo</div> </div> </div> This would end up displaying things just like the current flexbox draft does, because for both #a and #b all the free space is used up before it reaches the new distribution round. I don't particularly like adding a property that acts like padding, only different, but I'm already planning to do that for between-child margins with flex-spacing. Shrug. (Personally, I think the rendering for (2) is the best - it actually *centers* things by squishing them as much as possible.) ~TJ
Received on Friday, 4 June 2010 22:46:25 UTC