W3C home > Mailing lists > Public > www-style@w3.org > February 2014

Re: [css-flexbox] element vs box

From: Peter Moulder <pjrm@mail.internode.on.net>
Date: Thu, 13 Feb 2014 22:29:24 +1100
To: www-style@w3.org
Message-ID: <20140213112924.GA30071@mail.internode.on.net>
Here are my remaining comments on your much welcomed element/box fixup commit.

Coming back to that paragraph in §3 that mentions adding a row to table 9.7:

  # If a box’s specified display is inline-flex and the box is floated or
  # absolutely positioned, the computed value of display is flex.
  # The table in CSS 2.1 Chapter 9.7 is thus amended to contain an additional
  # row, with inline-flex in the "Specified Value" column and flex in the
  # "Computed Value" column.

I think the table amendment can stay as is, we just need to change the
description of that in the first two lines.  It's actually a bit awkward
to give in a single sentence the exact conditions in which that table
is applied (e.g. the existing description leaves out the root case and the
parent-flex-container case); I suggest a different approach, e.g.

  | If the specified value of 'display' is 'inline-flex', then the computed
  | value becomes 'flex' in certain circumstances:
  | the table in CSS 2.1 section 9.7 is amended to contain ...

(i.e. removing the word "thus", and incidentally also changing "Chapter 9.7" to
"section 9.7").

There are misleading indications of how floats are handled: section 4 says that
only in-flow children are flex items, which I would take to mean that
float:something elements simply don't generate flex items (and are instead
handled much like abspos elements are).  Alternatively, one could say that
the issue is that "in-flow box" isn't a well defined concept.  (CSS 2.1 defines
only whether an element is in-flow, and does so in terms of whether the element
is "floated", which itself isn't very clearly defined in this case.)

We'll come back to how floats are handled, but for now we'll get the section 2
definitions out of the way, while avoiding using the phrase "in-flow".

In section 2 (Terminology), the second sentence needs to be qualified with
"that are not absolutely positioned" to avoid conflicting with what section 4
‘Flex Items’ says about abspos children not being flex items.

As noted in another thread, I also believe there needs to be a clear definition
of "flex item", and that this can be accomplished by changing these sentences
in section 2 to

  | A <dfn>flex container</dfn> is the box generated by an element with a
  | computed 'display' of 'flex' or 'inline-flex'.
  | A <dfn>flex item</dfn> is a child of a flex container,
  | other than an absolutely positioned child.

and removing the <dfn> markup from the section 4 sentence.  (The "are called"
construct could be interpreted as merely giving an example of flex items rather
than a definition, as does the "becomes" approach in section 4.)

A related problem is that the text at the start of section 4 (before the first
colon) isn't true considering the abspos case (assuming that we consider abspos
boxes to still be among the contents of its parent).

As section 2 already has a definition (if the above change is accepted), then I
suggest that section 4 start with a non-normative description of the situation
from the point of elements, to give an intuitive feel for how things happen.

  | Loosely speaking, the flex items of a flex container are the boxes
  | generated from the children (and text nodes and pseudo-element children)
  | of the element that generated the flex container, other than absolutely
  | positioned children.

It might also mention

  | Box generation proceeds as usual inside elements whose 'display'
  | is 'flex' or 'inline-flex', except [something about floats and possibly
  | text nodes, see below].

The section needs to say something about floats and text nodes, but there are
a couple of behavioural questions that need to be decided first.

Regarding text nodes:

  - I'm not sure of the intended behaviour for whitespace text nodes: should
    white-space-only text nodes behave any different from if not present?
    If not, then I suggest that it not become a flex item at all.  (That
    reduces the risk of it unintentionally interacting with other bits of
    the spec that talk about flex items.)

  - I'm not sure that I understand the whitespace provision: the "can be
    affected by the 'white-space' property" formulation looks like it's
    trying to do something different from CSS 2.1 section 9.2.1's
    "collapsible whitespace" provision (and section's "white space
    that would subsequently be collapsed away" provision).  For example, my
    understanding of the mention of the word "property" in the existing text
    in css-flexbox is that it's talking about the white-space property
    generally rather than talking about the particular value of this property
    effective for the element that contains that white space, i.e. I'd expect
    from this text that an all-white-space text node in a display:flex
    element would behave the same regardless of that element's value of
    'white-space'.  Whereas I think that the more natural thing to specify is
    that box generation for child nodes of a display:flex element procedes
    pretty much as usual (other than computed 'float' being none), such that
    a box (and hence displayed flex item) gets generated for all-white-space
    if the parent's 'white-space' is 'pre' but not if 'normal'.

Regarding floats:

  - What should happen to consecutive elements whose specified 'display' is
    'table-cell' and whose specified 'float' is not 'none' (and whose
    specified 'position' is static), and whose parent element has a 'display'
    of '(inline-)flex' ?  Per the existing spec, part of the answer is that
    the table fixup provisions in the flexbox spec don't occur until boxes
    have already been generated; to decide what boxes get generated, we first
    apply CSS 2.1 table 9.7, and find that the computed 'display' of these
    cell elements is 'block', and computed 'float' is the specified
    non-'none' value, so the behaviour should be the same as for
    display:block float:something elements, with no applicable table fixup.

    That brings us to the simpler question:

  - What should be the behaviour for an element with display:block
    float:something (and position:static) and whose parent element has
    display:(inline-)flex ?  I'll assume that the intent is that it
    generate a flex item and not float, but there's also the question
    of what the computed value of 'float' for the element is
    (as is relevant for corner cases such as display:inherit).

I tried testing how chromium answers these questions, but it looks like my
installed version of chromium doesn't even apply the normal table-fixup rule
(if I've correctly written the test case at

Still, I do get one interesting result from that test case, namely that
in the one implementation I tested, an element with float:something specified
and a display:flex parent element has a computed 'float' of none (as tested by
a child with float:inherit).

Without giving too much thought, I'm guessing that all of this float-related
behaviour (especially float:inherit) is something without much author
preference, and on that basis I suggest specifying whatever behaviour a
majority of existing implementations have.  What do other implementations do?
For now, I'll go with making the computed value of 'float' for the element be
'none'.  I would do this by having css-flexbox specify that CSS 2.1 section 9.7
is amended to say that elements with a display:(inline-)flex parent have a
computed value of 'float' of none.

The other arbitrary choice to make is what to do with adjacent elements with
display:table-* float:something and a display:(inline-)flex parent element.
Again, without giving much thought, this sounds like a truly bizarre combination
so seems like it doesn't matter much what we specify (e.g. whether we leave the
existing CSS 2.1 9.7 mechanism to apply first, resulting in two display:block
flex items, or whether we insert something before the relevant "Otherwise"
rule that does that, so that that rule doesn't fire, and we end up with a
single anonymous-table flex item).

CSS 2.1 section 9.7 is the best place to specify the computed value of
'float', so let's first skip forward to the part of css-flexbox section 4
that deals with this section:

  # The computed 'display' of a flex item is determined by applying the table
  # in CSS 2.1 Chapter 9.7

This has the same box-tree / computed-'display' circularity as the reference to
section 9.7 mentioned in my previous message in this thread.  We can fix this
and specify the 'float' stuff at the same time as follows:

  | CSS 2.1 section 9.7 is amended to insert the following additional rule
  | after the existing rule 2:
  |   2b. Otherwise, if the parent element has a computed 'display' of 'flex'
  |       or 'inline-flex', then the computed value of 'float' is 'none',
  |       and the computed value of 'display' is the specified value if
  |       the specified value is an internal table value (i.e. is one of
  |       ...), or set according to the table below if the specified value
  |       is not an internal table value.

(In particular, the inserted rule shouldn't mention "flex item", because not
all of these elements will generate flex item boxes.)

[Note that both the above and the element-to-box transformation description in
 section 4 must somewhat go out of their way to have table fixup occur
 (i.e. for adjacent internal table things to be merged to a single table flex
 item rather than a number of display:block flex items), and that the one
 implementation I tested happens not to implement table fixup (if I'm correctly
 interpreting what I see).  So you might consider whether the table coalescing
 is something you want for authors or whether you were just guessing that that
 would be the easiest.  (I'd guess that you do want it and that it wouldn't be
 too hard for implementations to honour, I'm just checking here.)]

The immediately following text in the flexbox spec

  # (except that internal table
  # [<del>elements</del>] boxes
  # are instead handled by anonymous box fixup, see below).

can and should now be removed (because it's no longer an exception).  Elements
whose specified 'display' is an internal table thing (i.e. table-*) continue to
get "as specified", and anonymous table object generation will proceed as normal
with no changes needed.  (The outermost anonymous table box will be
display:table by the existing rules in CSS 2.1, because the parent element's
'display' is not 'inline' but '(inline-)flex'.)

Incidentally, once CSS has a normative description of box generation, I think
the near-following text about table fixup can become a non-normative note.  It
almost can already, except that the CSS 2.1 text for table fixup is currently
written in terms of making *changes* to a box tree [without even mentioning how
those initial boxes relate to elements], rather than describing a single box
tree that the rest of CSS (such as this bit of the flexbox spec) wants.

You might even consider adding a comment along the lines

  | <!-- Should be made non-normative once CSS has a description of
  |      anonymous table object generation that generates a single box tree
  |      rather than making changes to a box tree. -->

The above is all the difficult bits.  Sorry if I've made a mistake, but it's
getting late.  The remaining comments are pretty straightforward.


  # exactly as if the flex items were reordered in the source document.

If talking about behaving as if reordering the source document, then I think it
worthwhile to clarify that 'order' has no effect on counter values, e.g.:

  | However, 'order' has no effect on counter values.

(Other places where one might consider mentioning counter values are sections
9.1 and 5.4.1.  My own conclusion was not to in each of these two cases.)


  # A value of auto for 'align-self'
  # computes to the value of 'align-items' on
- # the element's parent,
+ # the flex item’s parent,
  # or <a value for=align-self>stretch</a> if
- # the element
+ # the flex item
  # has no parent.

This change should be reverted: the text in question is defining the computed
value of the 'align-self' property, which needs to be done whether or not the
element ultimately generates a flex-item box.  (E.g. because "all properties
defined in this specification also accept the inherit keyword as their property

One other change included in this commit is changing a prose condition for the
over-constrained-aspect-ratio case to the form of an unordered list (and,
incidentally, changing the behaviour for that condition).  In that unordered list
("If the flex item has ..."), may I suggest adding semicolon after the first
item and "; and" after the second ?  This just saves a bit of time working out
whether "and" or "or" is intended.

That's all I noticed.  Thanks for taking the time to fix these box generation
things; we're slowly working our way towards having the box tree being defined
in a way likely to be implemented interoperably.

Received on Thursday, 13 February 2014 11:29:44 UTC

This archive was generated by hypermail 2.4.0 : Monday, 23 January 2023 02:14:37 UTC