Are flex items block level element? - css

Flex items are element of flex level, but is that an element of the block level?
According to Chapter 4 of CSS Flexible Box Layout Module Level 1, flex items are considered to be at the flex level and not at the block level.
A flex item establishes an independent formatting context for its contents. However, flex items themselves are flex-level
boxes, not block-level boxes: they participate in their container’s flex formatting context, not in a block formatting context.
However, if you read chapter 4 later, it is written that the flex item's display value will be "blockified".
Does blockified indicate that the element is block level? If so, the "flex item is flex level" described above is a mistake.
The display value of a flex item is blockified: if the specified display of an in-flow child of an element generating a flex container is an inline-level value, it computes to its block-level equivalent. (See CSS2.1§9.7 [CSS21] and CSS Display [CSS3-DISPLAY] for details on this type of display value conversion.)
What does "blockified" mean here? Also, are flex items at the flex level? Or is it a blockified block level?
If it interprets as a specification, it will be the contradictory conclusion that "flex item is flex level, not block level but it becomes block level by blockified".

Both specifications are, of course, correct, but you forget the keyword display in the second section. Each element has a display value and for flex items this value is block which means that if, for example, you specify inline-block it will get computed to block. If you specify inline-grid, it will get computed to grid and so on.
if the specified display of an in-flow child of an element generating a flex container is an inline-level value, it computes to its block-level equivalent
So flex items are flex-level boxes with a display: block; value but they aren't block-level boxes.
Related: Usage of display property of flex box items
To make it easier, imagine you have two worlds, the outside world and the inside world. If we look at a flex item from the outside world, it's a flex-level box participating in its container's flex formatting context. From the inside world, it's a block element which means that an element inside a flex item will see the flex item as a block element.
If you set inline-[flex/table/grid/block] to the flex item it will be seen as a [flex/table/grid/block] container from the inside. The inline is gone because it's blockified.

Related

What is the relation between "block-level box", "block container box" and "block box" in CSS? [duplicate]

I am reading CSS Spec 2.1 and find the concepts hard to distinguish:
Except for table boxes, which are described in a later chapter, and replaced elements, a block-level box is also a block container box. A block container box either contains only block-level boxes or establishes an inline formatting context and thus contains only inline-level boxes. Not all block container boxes are block-level boxes: non-replaced inline blocks and non-replaced table cells are block containers but not block-level boxes. Block-level boxes that are also block containers are called block boxes.
May I interpret the description above as follow?:
Your interpretation is correct.
Here are some additional details:
The reason a table box is not a block container is because it establishes a table layout, not a block layout. Content goes into the cell elements rather than the table element, which is why it is the cell boxes that are block containers rather than the table box itself.
A replaced element doesn't contain any other content and therefore cannot be a block container.
The only difference between a block box and an inline-block is that the former is block-level while the latter is inline-level. Hence the display values display: block and display: inline-block respectively. As both are block containers, there is no difference in how their contents are formatted.
Note that replaced elements and table boxes can be either inline-level or block-level. Inline tables and inline replaced elements are simply excluded from the section you quote because that section only pertains to block-level boxes; you'll find references to them elsewhere in section 9, or in sections 10 and 17 respectively.
Also, even though a block container box can only either contain block-level boxes or inline-level boxes, you can still mix both in the same block container box; internally it simply segregates the block-level and inline-level boxes via anonymous block boxes.
Remember that HTML is a tree so each node can act as both a parent (of children) and child (of a parent)
Bearing this in mind, things start to make sense, Block-level box refers to box act as chlid
Block-level boxes are boxes that participate in a block formatting
context.
On the other hand, block container box refer to a parent who can contain others
A block container box either contains only block-level boxes or
establishes an inline formatting context and thus contains only
inline-level boxes
Just like a node can either be a child and a parent, an HTML node can either act as a parent(block container box) or child (block-level box) or BOTH
For example, if children in a node are not allowed (replaced element), it can never be a parent, it can only be a child (Block-level boxes) at most, not a parent (block container box)
And there is no reason to prevent a non-block parent contain a block parent. An inline-block itself is not a block, but it can contain block-level box
The point is a spec is easier to understand from a parent-child view

What is the difference between display:grid and display:inline-grid? [duplicate]

I noticed that people covered specifics of some display properties in a 1:1 comparison, but there are quite a few that have not been covered in illustrating the differences. Could someone explain the differences between the various inline-something display tags?
A more elaborated definition over places like w3schools would do wonders.
The only difference, for any display type that has block and inline variants, is that the inline-* display type has the box laid inline (i.e. in an inline formatting context) while the other has the box formatted as a block-level box, subject to most of the same formatting conventions as other block-level elements in a block formatting context. The difference between a block-level box and an inline-level box is covered in depth elsewhere.
Everything concerning how the box lays out its contents is pretty much the same (the specifics of which, of course, are governed by the display type itself); any other nuanced differences would have been stated explicitly in the spec. As far as I'm aware, there are in fact no such differences.
When in doubt, prefer block-level display types. If you find yourself asking whether inline-level is appropriate, chances are the answer is no. Certain scenarios may prevent a box from ever being formatted as an inline-level box anyway, such as absolute positioning or floating, or being formatted as a flex item or grid item instead. The result is a direct conversion from the inline-* variant to its usual block variant. That is, inline-block is converted to block, inline-table to table, inline-flex to flex, and inline-grid to grid. Again, this does not directly affect how an element's contents are formatted, not as far as the specifications go.
Examples of each display type and its inline-level counterpart follow.
In CSS2.1, section 9.2.4 describes block and inline-block as follows:
block
This value causes an element to generate a block box.
inline-block
This value causes an element to generate an inline-level block container. The inside of an inline-block is formatted as a block box, and the element itself is formatted as an atomic inline-level box.
Note that "block box" is a shorthand for "block-level block container", and a block container is something that can contain block-level boxes.
You can see that both of these two values cause an element to generate a block container box, in which its contents will always follow the same set of formatting rules, but that block container box itself is either formatted as block-level, or inline-level.
There is one additional difference between block and inline-block: an inline-block box always establishes a new block formatting context; block boxes only do so under a set of conditions. This does not hold true for any of the other display types that have block-level and inline-level counterparts.
Section 17.2 describes table and inline-table as follows:
table (In HTML: TABLE)
Specifies that an element defines a block-level table: it is a rectangular block that participates in a block formatting context.
inline-table (In HTML: TABLE)
Specifies that an element defines an inline-level table: it is a rectangular block that participates in an inline formatting context).
The Flexbox module describes flex and inline-flex as follows:
flex
This value causes an element to generate a block-level flex container box.
inline-flex
This value causes an element to generate an inline-level flex container box.
And the Grid Layout module describes grid and inline-grid as follows:
grid
This value causes an element to generate a block-level grid container box.
inline-grid
This value causes an element to generate an inline-level grid container box.
Again, in all of these scenarios, a table, a flex container, or a grid container will behave exactly the same way whether it is block-level or inline-level. A flex container always establishes a flex formatting context for its flex items, and a grid container always establishes a grid formatting context for its grid items.

What are allowed values of the `display` property for a flex-item? (layout of flex-item’s children is irrelevant)

All children of a flex container (designated by display: flex or display: inline-flex) are automatically made flex items. There is no display property for a flex item; instead, we set it to some other value depending on how we want the children of the flex item to be laid out.
So, if I set display to X value on Y element (taking into account that the Y participates in a flex context, that is Y is a flex-item) can I be sure that I will always get the flex-item that behaves (in this formatting context, in the flex container) like a block-level element?
(In other words, the Y participates in a block formatting context regardless of whether X=block/inline/table-cell/inline-grid/…etc , right?)
X – non-block value
Y – flex-item, html element
This:
<div id="flex-container" style="display:flex">
<div id="flex-item" style="display: inline;">item</div>
</div>
equals to this (without any side effects)
<div id="flex-container" style="display:flex">
<div id="flex-item" style="display: block;">item</div>
</div>
The only condition for being a flex item is being an in-flow child of a flex container.
Note this means a contiguous run of text can be wrapped inside an anonymous flex item which do not correspond to any element, and an element child of a flex container might not be a flex item if any of the following
It is absolutely positioned
an absolutely-positioned child of a flex container does not participate in flex layout.
It has display: contents
The element itself does not generate any boxes, but its children and
pseudo-elements still generate boxes as normal. For the purposes of
box generation and layout, the element must be treated as if it had
been replaced with its children and pseudo-elements in the document
tree.
Its children will become the flex items instead (unless something from this list applies to them).
It has display: none
The element and its descendants generates no boxes.
It has box-suppress: discard
The element generates no boxes at all.
It has box-suppress: hide
The element generates boxes as normal, but those boxes do not
participate in layout in any way, and must not be displayed.
Previously, if a child of a flex container had a display value that generated an anonymous parent, that parent became the flex item instead of the child. This changed and now the child becomes the flex item, and no parent is generated.
Apart from that, yes, the display value should not prevent an element from being a flex item.
Be aware that flex items are blockified, so for example inline-block becomes block, inline-table becomes table, inline-flex becomes flex, etc.
This means that, whatever the specified outer display role, the flex item will always be block-level.
Basically, the display property, when used on a flex item, is only useful to set its inner display layout model, e.g. that you want the flex item to be a flex container for its contents.
A flex item establishes a new formatting context for its
contents. The type of this formatting context is determined by its
display value, as usual. However, flex items themselves are
flex-level boxes, not block-level boxes: they participate in their container’s flex formatting context, not in a block formatting
context.
(The terminology differs a bit, the Display spec says a flex item is block-level in the sense of its outer display role, the Flexbox spec says it's not block-level in the sense that the formatting context in which it participates is not a block one)

CSS Spec: block-level box, block container box and block box

I am reading CSS Spec 2.1 and find the concepts hard to distinguish:
Except for table boxes, which are described in a later chapter, and replaced elements, a block-level box is also a block container box. A block container box either contains only block-level boxes or establishes an inline formatting context and thus contains only inline-level boxes. Not all block container boxes are block-level boxes: non-replaced inline blocks and non-replaced table cells are block containers but not block-level boxes. Block-level boxes that are also block containers are called block boxes.
May I interpret the description above as follow?:
Your interpretation is correct.
Here are some additional details:
The reason a table box is not a block container is because it establishes a table layout, not a block layout. Content goes into the cell elements rather than the table element, which is why it is the cell boxes that are block containers rather than the table box itself.
A replaced element doesn't contain any other content and therefore cannot be a block container.
The only difference between a block box and an inline-block is that the former is block-level while the latter is inline-level. Hence the display values display: block and display: inline-block respectively. As both are block containers, there is no difference in how their contents are formatted.
Note that replaced elements and table boxes can be either inline-level or block-level. Inline tables and inline replaced elements are simply excluded from the section you quote because that section only pertains to block-level boxes; you'll find references to them elsewhere in section 9, or in sections 10 and 17 respectively.
Also, even though a block container box can only either contain block-level boxes or inline-level boxes, you can still mix both in the same block container box; internally it simply segregates the block-level and inline-level boxes via anonymous block boxes.
Remember that HTML is a tree so each node can act as both a parent (of children) and child (of a parent)
Bearing this in mind, things start to make sense, Block-level box refers to box act as chlid
Block-level boxes are boxes that participate in a block formatting
context.
On the other hand, block container box refer to a parent who can contain others
A block container box either contains only block-level boxes or
establishes an inline formatting context and thus contains only
inline-level boxes
Just like a node can either be a child and a parent, an HTML node can either act as a parent(block container box) or child (block-level box) or BOTH
For example, if children in a node are not allowed (replaced element), it can never be a parent, it can only be a child (Block-level boxes) at most, not a parent (block container box)
And there is no reason to prevent a non-block parent contain a block parent. An inline-block itself is not a block, but it can contain block-level box
The point is a spec is easier to understand from a parent-child view

Display property differences for inline-*something*

I noticed that people covered specifics of some display properties in a 1:1 comparison, but there are quite a few that have not been covered in illustrating the differences. Could someone explain the differences between the various inline-something display tags?
A more elaborated definition over places like w3schools would do wonders.
The only difference, for any display type that has block and inline variants, is that the inline-* display type has the box laid inline (i.e. in an inline formatting context) while the other has the box formatted as a block-level box, subject to most of the same formatting conventions as other block-level elements in a block formatting context. The difference between a block-level box and an inline-level box is covered in depth elsewhere.
Everything concerning how the box lays out its contents is pretty much the same (the specifics of which, of course, are governed by the display type itself); any other nuanced differences would have been stated explicitly in the spec. As far as I'm aware, there are in fact no such differences.
When in doubt, prefer block-level display types. If you find yourself asking whether inline-level is appropriate, chances are the answer is no. Certain scenarios may prevent a box from ever being formatted as an inline-level box anyway, such as absolute positioning or floating, or being formatted as a flex item or grid item instead. The result is a direct conversion from the inline-* variant to its usual block variant. That is, inline-block is converted to block, inline-table to table, inline-flex to flex, and inline-grid to grid. Again, this does not directly affect how an element's contents are formatted, not as far as the specifications go.
Examples of each display type and its inline-level counterpart follow.
In CSS2.1, section 9.2.4 describes block and inline-block as follows:
block
This value causes an element to generate a block box.
inline-block
This value causes an element to generate an inline-level block container. The inside of an inline-block is formatted as a block box, and the element itself is formatted as an atomic inline-level box.
Note that "block box" is a shorthand for "block-level block container", and a block container is something that can contain block-level boxes.
You can see that both of these two values cause an element to generate a block container box, in which its contents will always follow the same set of formatting rules, but that block container box itself is either formatted as block-level, or inline-level.
There is one additional difference between block and inline-block: an inline-block box always establishes a new block formatting context; block boxes only do so under a set of conditions. This does not hold true for any of the other display types that have block-level and inline-level counterparts.
Section 17.2 describes table and inline-table as follows:
table (In HTML: TABLE)
Specifies that an element defines a block-level table: it is a rectangular block that participates in a block formatting context.
inline-table (In HTML: TABLE)
Specifies that an element defines an inline-level table: it is a rectangular block that participates in an inline formatting context).
The Flexbox module describes flex and inline-flex as follows:
flex
This value causes an element to generate a block-level flex container box.
inline-flex
This value causes an element to generate an inline-level flex container box.
And the Grid Layout module describes grid and inline-grid as follows:
grid
This value causes an element to generate a block-level grid container box.
inline-grid
This value causes an element to generate an inline-level grid container box.
Again, in all of these scenarios, a table, a flex container, or a grid container will behave exactly the same way whether it is block-level or inline-level. A flex container always establishes a flex formatting context for its flex items, and a grid container always establishes a grid formatting context for its grid items.

Resources