W3C home > Mailing lists > Public > www-style@w3.org > April 2010

Re: [CSS3] horizontal/vertical-align ?

From: Tab Atkins Jr. <jackalmage@gmail.com>
Date: Sun, 25 Apr 2010 09:10:20 -0700
Message-ID: <q2xdd0fbad1004250910qd86c4b5ch575a21b0d7aadbf2@mail.gmail.com>
To: Andrew Fedoniouk <news@terrainformatica.com>
Cc: "L. David Baron" <dbaron@dbaron.org>, www-style@w3.org
On Sun, Apr 25, 2010 at 12:30 AM, Andrew Fedoniouk
<news@terrainformatica.com> wrote:
>> Let's say you instead had this:
>>
>> <p>foo <img height=400px> <i height=1*>bar</i></p>
>>
>> What's the height of the <i>?
>>
>
> vertical flexes in inline-block elements are computed against line box. So
> that <i> will have 400px height.

And if the p has a line-height:30px on it?  Does anything change if
the <img> has vertical-align:middle or text-top?  What if there are
two such <img>s, one of which is vertical-align:text-bottom and the
other is vertical-align:text-top?

> On "adding display:table did not make..."
>
> A lot of code relies on   display: none;  display: block; to switch
> visibility. If suddenly <table> transforms into just a display:block it is a
> trouble.
> Before the display:table all that blocks were just display:block's.
> That was a bit risky decision to change display type of elements
> already published in the wild.

That was broken code in the first place, as it didn't work on inlines,
inline-blocks, or list-items.  Adding support for table layout did
indeed mean changing the display type of an element, but it was
apparently fine, since all the browsers did it.

This is a different situation, though.  Flexboxes are an entirely new
type of display.  Nobody is going to be surprised by a <flexbox>
element suddenly changing from display:block to display:box.


>>> I am not quite following you here.  What meaning you give to 'static'?
>>> I suspect it is far from "position:static" right?
>>
>> The term is defined in CSS2.1.  It just means the normal way of laying
>> out text and block elements.  Everything that's not absolutely
>> positioned, a table element, or a ruby element uses static layout to
>> position itself.
>>
>
> I am not aware "static layout" term, sorry.
>
> I know that position:static is a static positioning. Static positioning
> means that for replacing such elements some CSS built-in algorithm used. No
> matter of the display. Table layout is a perfectly static layout. That is
> why my confusion.

Like I said, it's defined in CSS2.1.  But I also just now explained
what it meant, and it's very obviously *not* referring to table layout
or similar.  Just mentally substitute "block and text flow" where
appropriate, if that helps.


>>> Say we have element with the style:
>>>
>>> min-width:100px;
>>> max-width:400px;
>>> width:200px;
>>> box-flex: 1.0;
>>>
>>> that is replaced alone in container having width:300px; then
>>> what be its used width?
>>
>> 300px, as it is capable of flexing to the full width of the container.
>>
>>
>>> What if container is say of width:150px; ?
>>
>> 150px, as it is capable of flexing itself that small.
>
> So width value is ignored here. Confusing at least.

Not ignored.  Just irrelevant.


>> Say you had a 400px wide container with two children; the first has
>> width:100px, the second has width:200px.  Both have box-flex:1.
>>
>> The natural widths of the children add up to 300px, so there's 100px
>> left over to use for flexing.  This gets split evenly between the two,
>> so you end up with the first child being 150px wide and the second
>> child being 250px wide.
>
> Uh... Cool...
>
> So if container has width, say, of 200px then width value of children is not
> used and distribution of widths will be 1:1. If it happens to be greater
> than 300px than suddenly distribution will be calculated using some other
> non-linear formula.
> Such non-monotonic functions are highly non-desirable in
> layout algorithms - may even cause oscillations. At least animations in such
> circumstances may bring some surprises.

I'm really not sure how you are getting yourself into this sort of
broken understanding.  Nothing I have said so far remotely suggests
what you are describing.  If the parent is 200px wide, then the
children are 100px too wide to fit.  Since they have equal flex
values, they both shrink by an equal amount, ending up at 50px and
150px wide.


> Thinking about how this setup will work when container will change from
> 200px to 300px. I cannot predict how all this will
> be calculated. Highly non-intuitive. At least for myself.

width of parent - (combined widths of children) = amount of flex (this
may be positive or negative)

Then distribute the flex between all children, in proportion to their
flex values.


>>> Is it possible to define all this somehow more formally?
>>> Like using math or so?
>>
>> That's all done in the draft.
>>
>
> In the one that is published? If yes then where?

In Chapter 5, Flexibility.


>>>> Since their box-flex values are the same, they'll shrink by the same
>>>> amount.  In the end, they'll be exactly the size necessary to fill
>>>> their parent, and the second box will still be 3px larger.
>>>
>>> Oh... but what the width value will be used for at the end?
>>
>> The width property provides a preferred width for the box, and is used
>> to figure out how much space is available for the flex calculation.
>>
>
> I do not understand this. You and spec say that used value of the width
> can be less than its declared (a.k.a. preferred ) value.  But it can be less
> only when no free space left in container. Are you sure you understand all
> this in the right way?

If the parent is too small to contain the children, the flexible
children will shrink in accordance with their box-flex value so that
they exactly fill the parent.  This is exactly in accordance with what
I've been explaining in previous emails, and in fact I'm merely
restating what I've already said at this point.


> And what happens if you have this:
>
> 1 { box-flex: 2.0; width: 30%; }
> 2 { box-flex: 2.0; width: 69%; }
>
> what would be their width ratio? 1:1 or close to 30:69? If later one then
> what box-flex value is used for? If 1:1 then the same question about widths.

Stop assuming that they end up 1:1.  That is almost always going to be
wrong unless you specifically set it up that way.  Your thinking is
poisoned by your own implementation of flexes.

In this case, there is 1% of free space left over.  Both children are
flexible, and they have the same amount of flexibility, so they get
the 1% distributed equally.  Thus the first will end up being 30.5%
width, and the second will be 69.5% width.

This is exactly the same as the situation I already described with the
boxes that are 100px and 200px in width.  Please, stop and digest what
I'm saying.  It's very simple, but it's slightly different from the
way that your implementation does things.


>>> Say in flow:horizontal I will want som elements to be aligned
>>> to top and some to bottom. As far as I understand that box-align
>>> will not allow me to do so, correct? If so then this is definitely bad
>>> as such layout are used already.
>>
>> Correct, flexbox does not allow that.
>>
>> Can you point me to pages that use this sort of layout?  I haven't
>> seen any so far, but new use-cases are always awesome to find.
>>
>
> Pretty much any page on the Web.
>
> display: box;
> box-orient: vertical;
>
> And now imagine that you have some headers centered. You have to be able to
> align elements individually.

If you're using a vertical flexbox to lay out a webpage, it's likely
that you're using box-align:center or stretch anyway, and so that all
works properly.  Do you have any examples of pages that would
specifically need both box-align:start and end within a single
flexbox, like you described?


> There is a question actually what margin:auto means in context of
> box-orient: vertical;

It means precisely what the draft says.  It describes exactly how to
compute widths and heights of elements, including what to do when the
margins or width/height are auto.


> Ok. For three elements in a container
>
> flow: horizontal;
> flow: "1 2"
>        "1 3";
>
> horizontal will replace elements in single row.
> Second declaration will make two rows with first child to span two rows. The
> difference only in the way how blocks will be laid out.
> Nothing changes in principle. The container itself will have the same
> display value and its children will use same metrics and principles
> of width/height, min/max calculations.

Using Flexbox and Template, both elements can have the same
display-outside value.  What I call "display-outside" and
"display-inside", you call "display" and "flow".  There's no
difference in mechanics, just in name.

The two elements will *not* lay their children out the same way,
however.  If you were using a flow:horizontal-flow box, and it wrapped
to two lines, the children on separate lines have no relationship to
each other.  On the other hand, with a template flow, the elements in
slot 2 and 3 must have the same width.


> In the same way as changing from box-orient: horizontal  to box-orient:
> vertical should not require introduction of brand new module in CSS with its
> own units and bunch of properties.

Of course not, a vertical and horizontal flexbox work nearly exactly the same.


> Actually I went even further. I've implemented flexes. So something I do
> understand. I hope so at least.

You understand *your implementation* of flexes.  It's very clear that
you don't understand how the Flexbox module works, though, and so far
you appear to be purposely avoiding understanding it, as you are
drawing conclusions that are flatly contradicted by previous examples
I explained.

~TJ
Received on Sunday, 25 April 2010 16:11:10 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 17:20:26 GMT