Block Level Element vs Block Formatting Context - html

What is the difference between a HTML element that is a block level element and a HTML element that forms a block formatting context?
Can a HTML element be both a block level element and form a block formatting context?
Does being a block level element imply that it forms a block formatting context, or conversely, does forming a block formatting context imply that it must be a block level element?
In a similar vein, how does this translate to inline elements and elements that form an inline formatting context?
(For some context, I've been trying to read Learn CSS Layout - The Pedantic Way but it's been a bit challenging to follow Chapter 1)

Note that this answer uses the term "box" in lieu of "element", as CSS makes a distinction between elements and boxes. For the purposes of this answer, an HTML element is represented by a single box in CSS layout. In reality an element may generate any number of boxes (or none at all, as in display: none), but that's outside the scope of this question.
Can a HTML element be both a block level element and form a block formatting context?
Yes. The criteria in which a block box (i.e. a block-level block container box) may establish a BFC are stated in section 9.4.1 of CSS2.1, namely:
floats,
absolutely positioned elements, and
"block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport)" (as directly quoted from the spec)
Does being a block level element imply that it forms a block formatting context, or conversely, does forming a block formatting context imply that it must be a block level element?
Neither:
The above answer implies that not all block boxes establish block formatting contexts. A block box with the CSS properties display: block; overflow: visible; float: none; position: static (or position: relative) does not establish a BFC.
Conversely, an inline-block is an example of a box that establishes a BFC, but is itself inline-level, not block-level.
In a similar vein, how does this translate to inline elements and elements that form an inline formatting context?
An inline box is an inline-level box whose contents participate directly in its parent's inline formatting context (see section 9.4.2). Notably, the only boxes that can establish inline formatting contexts are block container boxes.
The difference between an inline box and an inline-block is that an inline-block's contents participate in the BFC that it establishes, not in the parent's IFC. Instead, only the inline-block itself participates in its parent's IFC.

Related

What is the difference between "block box" and "block-level element"?

This MDN doc says:
In CSS we broadly have two types of boxes - block boxes and inline
boxes.
But in this MDN doc that talks about normal flow, block boxes are never mentioned. Only block-level elements are mentioned.
What is the difference?
Block vs Block-Level
Lots. Block boxes are both block-level and also block containers. That's display:block, display:flow-root, the principal box of display:list-item and the table wrapper box of display:table.
Boxes that are block-level, but not block containers, and therefore not block boxes are those which have e.g. display:flex, display:grid and the table grid box of display:table
Boxes that are block containers, but not block-level, and therefore not block boxes are those which have e.g. display:inline-block and display:table-cell.
Stating that there are broadly two types of boxes - block and inline - is at best misleading, if not outright wrong. We could better say that there are broadly two types of boxes - block-level and inline-level, but even then, only broadly. Block-level boxes are participants in a Block Formatting Context. Inline-level boxes are participants in an Inline Formatting Context. Boxes that are participants in other formatting contexts, such as flex items, grid items, and some of the internal table and ruby boxes are neither.
Elements vs Boxes
Elements are objects of SGML, HTML and DOM. Boxes are objects of CSS. A block-level element is one that when the CSS box tree is being formed, by default generates at least a principal box which is block-level.

What is the relationship between 'Normal Flow' and 'BFC'?

I read this in MDN's Introduction to formatting contexts:
Introduction to formatting contexts
The outermost element in a document that uses block layout rules establishes the first, or initial block formatting context. This means that every element inside the <html> element's block is laid out according to normal flow following the rules for block and inline layout. Elements participating in a BFC use the rules outlined by the CSS Box Model, which defines how an element's margins, borders, and padding interact with other blocks in the same context.
So can we think of 'Normal Flow' as the way to layout in BFC, and Normal Flow is the largest BFC created by the root element (HTML)
My mental model
Is this rough mental model correct?
I consulted the documentation:
Introduction to formatting contexts
Block and inline layout in normal flow
Some concepts from the CSS specification documentation such as:'visual formatting model','block container box','block level box','block box'.
It used to be a decent approximation. Less so nowadays that we have Flex formatting contexts and Grid formatting contexts.
To grasp normal flow, a better place to start is The glossary in the CSS Level 3 Display specification, which says:
out-of-flow
in-flow
A box is out-of-flow if it is extracted from its expected position and interaction with surrounding content and laid out using a different paradigm outside the normal flow of content in its parent formatting context. This occurs if the box is floated (via float) or absolutely positioned (via position). A box is in-flow if it is not out-of-flow.
Note: Some formatting contexts inhibit floating, so that an element with float: left is not necessarily out-of-flow.
So normal flow is all content that's not floated or absolute positioned (including for this purpose, fixed positioned). You probably shouldn't tie this too closely to any particular formatting context.

Why are inline-level boxes not being laid out according to block formatting context rules despite being inside one?

I am trying to understand the relationship between formatting context and inner and outer display types.
On one hand, the official explanation, in W3 and related websites, says that, all boxes have a formatting context. They either create one, or continue the one of their parent, which too, either created a formatting context, or continued one of its parent, and so on until the initial block formatting context established by the HTML element.
Elements inside a block formatting context are laid out according to block formatting context rules. So that means that, when you insert a div inside another div, the child div is laid out according to the block formatting context rules, because its parent has a block formatting context rules.
So then why aren't elements with display:inline or inline-flex not being laid out according to block formatting context rules?
The explanation states that, the inner display type defines the formatting context which determines the way elements will be laid out. The outer display type dictates how the principle box participates in the flow layout.
This last explanation confuses me, because, isn't the way elements participate inside a container determined by the formatting context of that container?
When you set the display type of a div to "flex", that element creates a flex formatting context inside of itself, however, on the outside, it still behaves according to block formatting context rules, because it is inside one, is that not correct? So, then, why is the same thing not happening with inline elements, or elements with display inline-flex? Why is their outer display type not block when they are inside one?
If changing the display property changes the formatting context inside the element, while its outer behavior is determined by the formatting context of ITS parent, then why are inline elements and inline-flex elements and probably others too not being laid out according to block rules when inside a block formatting context?
then why are inline elements and inline-flex elements and probably others too not being laid out according to block rules when inside a block formatting context?
You are missing a small piece of the puzzle that is called anonymous block box
In other words: if a block container box (such as that generated for the DIV above) has a block-level box inside it (such as the P above), then we force it to have only block-level boxes inside it.
In order to force only block level boxes inside a block formatting context we put our inline elements (or inline-block ones) inside an anonymous block box. That anonymous box will then create an inline formatting context inside it for the inline elements.
Considering this, all the rules you have described will be accurate.

Contradiction in Definition of Inline-Level Boxes and Inline Boxes (W3C)

W3C source for the quotes below.
The following values of the 'display' property make an element
inline-level: 'inline', 'inline-table', and 'inline-block'
Thus, an element with display: inline-block is an inline-level element.
Inline-level elements generate inline-level boxes, which are boxes
that participate in an inline formatting context.
Thus, all inline-level boxes participate in an inline formatting context.
An inline box is one that is both inline-level and whose contents
participate in its containing inline formatting context
If all inline-level boxes participate in an inline formatting context, and an inline box is one that is both an inline-level box and participates in an inline formatting context, it must be true that all inline-level boxes are inline boxes, and vice versa.
And finally, here comes the statement that then breaks the logic:
Inline-level boxes that are not inline boxes (such as replaced
inline-level elements, inline-block elements, and inline-table
elements) are called atomic inline-level boxes...
In other words:
First we are told, via logical implication, that all inline-level boxes are inline boxes. Then, we are told the opposite: That several inline-level boxes (like those generated by elements with display: inline-block), are in fact not inline boxes.
Am I missing something or are the quotes contradicting each other?
EDIT
I found the following post by #BoltClock, which is really good: CSS Spec - Atomic Inline Level Boxes
I also posted an answer to another question, after understanding the whole concept a bit better. It can be found here: Difference between inline box and atomic inline box
There is not a contradiction in the standard, but we have to read carefully to spot the differences.
Inline-level boxes are boxes that participate in an inline formatting context.
An inline box is a inline-level box whose contents participate in its containing inline formatting context
A span-element inside a paragraph is an inline box, because the text inside the span-element participate in the paragraphs' surround content.
An element with display: inline-block; will flow with surrounding content as if it were a single inline box, but since this element actually will generate a block element box, the elements contents do not participate in its containing inline formatting context.

Difference between inline box and atomic inline box

Consider the following code:
<div></div>
div{
display: inline-block;
}
div block is generated atomic inline-level box now. As said in spec. 9.2.2
Inline-level boxes that are not inline boxes (such as replaced
inline-level elements, inline-block elements, and inline-table
elements) are called atomic inline-level boxes because they
participate in their inline formatting context as a single opaque box.
What does 'opaque' mean in this case? Is inline boxes participated in the inline formatting context as a transparent box?
So I'm interested in what difference between atomic inline-level box and inline box?
From the WC3 CSS2.1 Specification, Chapter 9 Visual formatting model:
An inline box is one that is both inline-level and whose contents
participate in its containing inline formatting context. A
non-replaced element with a 'display' value of 'inline' generates an
inline box.
Inline-level boxes that are not inline boxes (such as
replaced inline-level elements, inline-block elements, and
inline-table elements) are called atomic inline-level boxes because
they participate in their inline formatting context as a single opaque
box.
Therefore
Elements with display: inline generates inline boxes.
Elements with display: inline-table | inline-block and replaced inline-level elements (like <img>) generates inline-level atomic boxes.
With regards to your question on what opaque means, #BoltClock explains it in a great way here:
CSS Spec - Atomic Inline Level Boxes
Opaque means that the box is a singular, solid unit, and that it
cannot be split across lines like an inline box can when its text
cannot all fit on a single line.
And here is some additional detail from me, that might help
Inline-level boxes includes boxes...
...whose content participate in its containing inline formatting context
These are called inline boxes
They are generated by elements with display: inline
Note the words "...whose content participate in its containing...". This means that inline-level child elements inside this inline-level box, are in the same inline formatting context as the parent. This, in turn, means that the individual child inline-level elements will separate and fall to a new line if there is white space (and the white-space property is not changed). In effect, the parent inline box will split into several boxes. Here, all the inline-level elements inside the parent inline box, live in one big happy inline formatting context.
...that participate in their inline formatting context as a single opaque box
These are called atomic inline-level boxes
They are generated by elements with display: inline-table | inline-block | inline-flex | inline-grid
Opaque means that the box is one single solid box
A consequence of that is that the box cannot be split, even if inline-level boxes inside it normally should fall to the next line
Instead, scrollbars would appear
Contents inside this atomic inline-level box does not participate in the same inline formatting context as its parent
And finally, as seen, inline-level boxes is a super-set of inline boxes.
Hope that helps someone in the future.
Indeed. Referring to Visual Formatting Model
<p>Some <em>emphasized</em> text</p>
anonymous inline boxes inherit inheritable properties from their
block parent box. Non-inherited properties have their initial value.
In the example, the color of the anonymous inline boxes is inherited
from the P, but the background is transparent