Identifying flex items
First, you need the box tree
To recap, every element node in the DOM tree gets to generate a box when the box tree is constructed by the browser. Text nodes always generate a text run, because they have the initial value of display
, which is inline
. Remember that if an element node has display: none
, then it doesn’t generate a box at all. And none of its descendant nodes in the DOM get to generate a box, either.
Pseudo-elements don’t exist in the DOM tree, but they do exist in the box tree if they have some content. For example, the first child box of the main
element’s box will be the box generated by the ::before
pseudo-element:
<style>
main::before {
content: 'Howdy!';
}
</style>
<main>
<p>
The box generated by the paragraph element will not be the first child of
the main element’s box.
</p>
</main>
Then, you find the flex container boxes in the box tree
Once you have the box tree, you look at all the boxes, and check if they have display: flex
or display: inline-flex
. Those that do are flex container boxes, and their children in the box tree will be laid out with Flexbox layout.
Flex item boxes are child boxes of the flex container box. But not every child of the flex container box is a flex item.
But not every single child of a flex container box is automatically laid out with Flexbox.
Boxes with position: absolute
and position: fixed
are not considered flex items
Boxes with position: absolute
and position: fixed
are not considered flex items, and are ignored as far as calculating Flexbox layout is concerner.
Text runs can’t be flex items, they have to be wrapped in a new box
Flexbox only deals with boxes. It can’t lay out text runs. That’s the job of Flow layout. But obviously we can center a text label inside a button element. What’s going on here?
We want to be able to size and position chunks of text, but Flexbox only deals with boxes... Here’s how Flexbox deals with this:
First off, any neighboring whitespace-only text runs are completely ignored. They’re not laid out at all. This is different from Flow layout, where whitespace does get laid out and rendered, and can cause subtle and annoying issues:
<p>
<span>Hello</span>
<span>World</span>
</p>
Text runs can’t be flex items, so neighboring non-whitespace text runs get wrapped in a box.
- This box is a child box of the flex container box.
- This box is called an anonymous flex item box because it doesn’t have a corresponding element in the DOM tree that generated it.
- This box lays out the text run children with Flow layout.
Floating is ignored in Flexbox, so any floated boxes are regular flex item boxes
Floating doesn’t do anything in Flexbox layout, so boxes that have a non-none value of float are still considered flex items.
Only boxes in the box tree can be laid out
Elements with display: none
or display: contents
don’t generate a box at all, and are not represented in the box tree. They don’t exist as far as Flexbox layout is concerned.