if this answer is to long, read the conclusion.
look at this screenshot:
the yellow bit indicates the margin of the h1 heading. What is important to understand, is that heading elements (h1 till h6) are block level elements.
then it is important to understand that browser have a default stylesheet (see this stakoverflow question), if we look into this stylesheet, we see this (this is the one for firefox):
h1 {
display: block;
font-size: 2em;
font-weight: bold;
margin-block-start: .67em;
margin-block-end: .67em;
}
which explains why headings are block level elements. but we also see margin-block-start which is a property which is not yet covered, but it acts very similar to margin-top. but the important note here is the em
, which means it is relative to the font-size (the bigger the font-size, the bigger the margin)
now that we understand div
and h1
are block level elements, we could start to try to understand the w3 documentation (which is complicated)
lets just say for now, that the condition are ideal for adjoining margins. But this part of the documentation is important:
Two margins are adjoining if and only if:
no line boxes, no clearance, no padding and no border separate them
both belong to in-flow block-level boxes
that participate in the same block formatting context
which we can reverse, meaning we can use padding to prevent the margins from adjoining.
now lets look at the second point, what does block level boxes mean? In the documentation you can click on it and get to this explanation:
Block-level elements are those elements of the source document that are formatted visually as blocks (e.g., paragraphs). The following values of the ‘display’ property make an element block-level: ‘block’, ‘list-item’, and ‘table’.
okay, as we just determined that h1 is a block, and div is a block as well (go look in the default stylesheet, you will see div is also has a display: block
property)
then now block formatting content:
Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with ‘overflow’ other than ‘visible’(except when that value has been propagated to the viewport) establish new block formatting contexts for their contents
so if you have a float (float: left;
) or a absolute element (position: absolute;
) a new block format is created, since you don’t have this, your h1 and div are in the same block format. (which a condition for adjoining margin to occur)
with other words, a whole lot more measures you can take to prevent adjoining margin (use overflow, and give it any value except visible)
conclusion: adjoining margins are confusing, difficult, and occur rarely because of all the conditions which have to be met.