This question is similar to this one (with an excellent answer), although mine doesn't pertain to float issues.
I recently ran into some trouble when trying to apply a margin to an only-child of a block-level element:
#parent {
background: rgba(255, 0, 0, 0.1);
}
#child {
margin: 30px 0;
padding: 20px;
background: rgba(0, 255, 0, 0.1);
}
<div id="parent">
<div id="child">Foo</div>
</div>
Although the margin is applied, the parent's background is not. This remains true unless siblings are added before and after the #child
, or (more interestingly in my opinion), an overflow
of any value other than visible
is set. Here is the same example but with an overflow value:
#parent {
background: rgba(255, 0, 0, 0.1);
overflow: auto;
}
#child {
margin: 30px 0;
padding: 20px;
background: rgba(0, 255, 0, 0.1);
}
<div id="parent">
<div id="child">Foo</div>
</div>
From CSS2.1 Section 9.4.1 - Block Formatting Contexts, I found the following:
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.
I'm really struggling to understand the rationale behind the "overflow other than visible" logic in this instance. The margins are seemingly not being clipped in this situation, as the only thing to change is the background. Could someone demonstrate why a value of overflow: visible
creates such a situation?
A new block formatting context can be created by adding any one of the necessary CSS conditions like overflow: scroll , overflow: hidden , display: flex , float: left , or display: table to the container.
A block formatting context (BFC) is a part of a visual CSS rendering of a web page. It's the region in which the layout of block boxes occurs and in which floats interact with other elements. A block formatting context is created by at least one of the following: The root element of the document ( <html> ).
overflow: hidden With the hidden value, the overflow is clipped, and the rest of the content is hidden: You can use the overflow property when you want to have better control of the layout. The overflow property specifies what happens if content overflows an element's box.
To activate the overflow property enclose the image, within a div of a particular width and height, and set overflow:hidden . This will ensure that the base container will retain its structure, and any image overflow will be hidden behind the container.
As I have covered in my answer to the question that you link to, the main reason overflow
values other than visible
result in a new block formatting context is due to implementation limitations relating to floats, even though the concept of overflow does not immediately appear to have a relationship with floats.
While the relationship between floats and collapsing margins is pretty simple (it never occurs), the fact that margins cannot collapse through the boundaries of an element with such a value for overflow
either is little more than a side effect of this change, because margins are defined not to collapse through any box that establishes a block formatting context, as described in section 8.3.1. I quote:
- Margins of elements that establish new block formatting contexts (such as floats and elements with 'overflow' other than 'visible') do not collapse with their in-flow children.
This includes both floats and elements with such a value for overflow
. The overflow itself does not actually have any direct effect on the margins.
When both the parent and the child are block-level elements that participate in the same block formatting context, they will collapse by default unless there is something in the way:
The top margin of an in-flow block element collapses with its first in-flow block-level child's top margin if the element has no top border, no top padding, and the child has no clearance.
The bottom margin of an in-flow block box with a 'height' of 'auto' and a 'min-height' of zero collapses with its last in-flow block-level child's bottom margin if the box has no bottom padding and no bottom border and the child's bottom margin does not collapse with a top margin that has clearance.
This explains why the parent's background does not extend until you try and block the margin collapse.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With