Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In flexbox, why do we define the container and not the elements themselves?

Tags:

css

flexbox

I'm trying to understand the flex property.

Why do we apply float and display: inline-block to the elements that are nested inside a container, while with display: flex, we define the container itself? How can the elements inside be display:block and still be positioned on the same row?

.flex {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  flex-direction: row;
}

@media (max-width: 600px) {
  .flex {
    flex-direction: column;
  }
}

#aaa {
  border: 3px solid black;
  flex: 2;
}

#aa {
  border: 3px solid black;
  flex: 1;
}

#a {
  border: 3px solid black;
  flex: 1;
}

#bbb {
  width: 300px;
}

#ccc {
  float: left;
  border: 5px solid yellow;
  width: 200px;
}

#ddd {
  clear: both;
}

.one {
  background: red;
  height: 50px
}

.two {
  background: green;
  height: 50px
}

.tree {
  background: blue;
  height: 50px
}

#eee {
  display: inline-block;
  width: 200px;
}
<div class=flex>
  <div id=a class="one">flex</div>
  <div id=aa class="two">flex</div>
  <div id=aaa class="tree">flex</div>
</div>
<div class=block>
  <div id=bbb class="one">block</div>
  <div id=bbb class="two">block</div>
  <div id=bbb class="tree">block</div>
</div>
<div class=float>
  <div id=ccc class="one">float</div>
  <div id=ccc class="two">float</div>
  <div id=ccc class="tree">float</div>
</div>
<div class=block>
  <div id=ddd class="one">block</div>
  <div id=ddd class="two">block</div>
  <div id=ddd class="tree">block</div>
</div>
<div class=block>
  <div id=eee class="one">block</div>
  <div id=eee class="two">block</div>
  <div id=eee class="tree">block</div>
</div>

CodePen demo

like image 430
Nave Hazan Avatar asked Jul 13 '17 13:07

Nave Hazan


Video Answer


1 Answers

In flexbox, why do we define the container and not the elements themselves?

The reason is twofold:

  1. Flex containers are the only things flex items can appear as children of, since only flex containers generate flex layout.
  2. Unlike anonymous block boxes and anonymous table boxes, there are no such things as anonymous flex container boxes.

So, a hypothetical display: flex-item wouldn't work unless the element's parent was a flex container, and since every child of a flex container automatically becomes a flex item anyway, this makes such a display type completely redundant.

Block-level and inline-level boxes, on the other hand, exist in many, many forms. Even flex containers can appear in block-level and inline-level forms, as display: flex and display: inline-flex respectively. Furthermore, display: block and display: inline-block actually have a lot in common, as they are both block containers. The only difference is that one is block-level and the other is inline-level (and the latter always generates a block formatting context, but that's not pertinent here).

So display: block and display: inline-block are actually very similar to display: flex and display: inline-flex respectively in that regard (see Difference between display:inline-flex and display:flex), the difference being that the former pair handles block layout or inline layout (see section 9.2 of the CSS2 spec), and the latter pair handles exclusively flex layout.

If you're asking why flexbox was designed this way, that's something only the CSSWG can answer with certainty, but I can provide an educated guess based on what I've stated above: Since block-level and inline-level boxes can exist in so many different forms for various internal layout types (block, table, flex, grid, etc), defining flex-level counterparts for every single layout type would become extremely unwieldy, even if they did introduce a concept of anonymous flex container boxes which would allow elements to exist as flex items in their own right. This is why css-display-3 redefines the display property to take the form of <display-outside> <display-inside> along with special and legacy values — to accommodate new layout types without having to redefine entire sets of keywords to go along with them.

Your flex items are display: block simply because that's their specified value of display. But they are laid out as flex items, which always obey a set of rules in flex layout, which are loosely based on a combination of various elements of block and inline layout without falling squarely within the domain of either one. This is similar to how a float or an absolutely positioned element cannot be inline even if you specify display: inline or display: inline-block — because floats and absolutely positioned elements always participate in block layout, never inline layout.

Speaking of floats, FYI, floats participate in block formatting contexts, and are therefore part of a certain subset of block layout. They follow a float model, but the float model is integrated with the rest of block layout rather than existing as a completely separate layout type.

like image 84
BoltClock Avatar answered Oct 12 '22 11:10

BoltClock