HomeGuideLabGlossary

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.

htmlbodymainTHE BOX TREE

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>
mainp::beforePseudo-elements don’t exist in the DOM tree, but do exist in the box tree

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.

htmlbodyp::beforemaindisplay: flexGot ya!

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.

p::beforemain??

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.

maindisplay: flex::beforeposition: absolutepYou’re a flex itemIGNORED

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>
::beforemainp"\n "IGNORED

Text runs can’t be flex items, so neighboring non-whitespace text runs get wrapped in a box.

buttonbutton"Play Nice Song""Play Nice Song"Sorry you can’t be a flex itemBetter!display: flexdisplay: flex

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.

mainbodydisplay: flexfloat: leftIGNOREDUm yeah no I don’t care about floating

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.

headdisplay: noneYOU WILL NEVER BE PART OF THE BOX TREE!