Search code examples
htmlcssflexboxvertical-alignment

Does a flex item not need to be an explicit element inside flex container?


<!-- HTML -->
  <body>
    <div class="header">
      My awesome website
    </div>
  </body>

/* CSS */
.header {
  height: 72px;
  background: darkmagenta;
  color: white;
  font-size: 32px; 
  font-weight: 900;
  padding-left: 16px;
  display: flex;
  align-items: center;
}

I'm attempting to vertically align the text, "My awesome website", inside the div using flexbox model.

What I understand about flexbox is that the flex container and flex item need to be parent and direct child elements, respectively. Setting display: flex turns header div into a flex container and setting align-items: center will center the flex items.

However, I noticed that "My awesome website" does not need to be an EXPLICIT child element in order for flexbox to treat it as a flex item and apply flex properties to it.

For example, I thought the code needed to look like the following in order for flex properties to apply:

<!-- HTML -->
  <body>
    <div class="header">
      <div>
        My awesome website
      </div>
    </div>
  </body>

Do flex container and flex items not always need to be explicit parent and direct child elements?


Solution

  • From the Specification:

    Each in-flow child of a flex container becomes a flex item, and each contiguous sequence of child text runs is wrapped in an anonymous block container flex item.

    The browser will create an "anonymous block container" for the text and this invisible block will become the flex item.

    But I highly recommend you to manually put your text inside a container because you should never make a text container a flexbox container.

    Here is an example of a bad result:

    .header {
      height: 72px;
      background: darkmagenta;
      color: white;
      font-size: 32px;
      padding-left: 16px;
      display: flex;
      align-items: center;
      justify-content: center;
      height: 200px;
    }
    <div class="header">
        My   <strong>awesome</strong>   website
    </div>
    
    <div class="header">
        <div>My   <strong>awesome</strong>   website</div>
    </div>

    I wrote a small article to explain this little quirk: https://dev.to/afif/never-make-your-text-container-a-flexbox-container-m9p