TL;DR Block formatting contexts establish an isolating container. float
and clear
only apply to elements within such a container.
About
Block formatting contexts (BFCs) are important for the positioning and clearing
of floats. The rules for positioning and clearing of floats apply only to
things within the same block formatting context.
Floats do not affect the layout of things in other block formatting contexts,
and clear
only clears past floats in the same block formatting context.
How to create a new block formatting context
A block formatting context is created by one of the following:
-
Preferred:
display: flow-root
float: (not "none")
-
position: absolute
orposition: fixed
display: inline-block
display: table-cell
overflow: (not "visible")
- and more, see https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Block_formatting_context Show archive.org snapshot
Example: A fluid main area with a right sidebar
In a two-column layout you don't want either column to clear content of the other. Float the sidebar to the right and you're set: its content now renders in the sidebar's own block formatting context.
However, a clear: <both|right>
in the main area still clears the sidebar, which is undesirable. You need to give the sidebar an own BFC. Since there is no actual "command" to create one, you need to hack it.
Below see a list of issues and side effects with BFC-creating properties on the main area.
Best solution: overflow: hidden
This is the only reliably working property, use it whenever you can. Caution: This will literally cut off any content that leaves the container. You must not specify a height on the main area so it can stretch as needed. If any content ever needs to overlap the main area's borders, try adding padding (no pun intended).
float
: Floating elements are taken out of their surrounding context, which is why a floating main area would not "know" about the location of the sidebar. Thus, it cannot responsively stretch to the sidebar's left edge. Bad.
position: <absolute|fixed>
: This is worse than floating. The main area will now grow out of its container and overlap e.g. the footer.
display: inline-block
: Again, an inline element will not stretch to the available width.
display: <table|table-cell>
: Tables also don't stretch to the available width. Adding width: 100%
will ignore the margin, making the main area "float" below the floating sidebar.