What's the containing block of floated elements?
The premise of your question is flawed. An absolutely positioned element cannot float, and a float cannot be absolutely positioned. From section 9.7:
[...] if 'position' has the value 'absolute' or 'fixed', the box is absolutely positioned, the computed value of 'float' is 'none' [...]
So you're not trying to find the containing block of a float here. You're trying to find the containing block of an absposed element.
Having said that, if you really must know, the containing block of a float is the same as for relatively positioned or non-positioned elements as I described in my answer to your previous question, since floats cannot be absposed.
Floating elements within a div, floats outside of div. Why?
The easiest is to put overflow:hidden
on the parent div and don't specify a height:
#parent { overflow: hidden }
Another way is to also float the parent div:
#parent { float: left; width: 100% }
Another way uses a clear element:
<div class="parent">
<img class="floated_child" src="..." />
<span class="clear"></span>
</div>
CSS
span.clear { clear: left; display: block; }
Do block elements ignore floating elements?
Several paragraphs after the one you quote, the spec says:
The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap the margin box of any floats in the same block formatting context as the element itself.
Although you've applied display: block
to your image, being an image it's a replaced element, and therefore the float cannot intrude into its bounds.
Only non-replaced block boxes that don't establish block formatting contexts and are in the same flow as a float may ignore the float.1 A block-level replaced element is not a block box, because a replaced element cannot be a block container box.2
1 You're probably thinking, that's a ridiculously specific statement, and it is. It's why terms like "block element" are considered extremely vague in CSS parlance. Then again, it doesn't help that CSS itself defines almost equally vague terms like "block box" to specifically refer to boxes that are both block-level boxes and block container boxes.
2 This does imply that "non-replaced block box" is somewhat of a tautology, which reinforces just how ridiculously specific that statement is.
Why do floated elements not overlap a block-element if they are defined after them in the HTML structure?
Thinking about the vertical progress of the Document Flow will answer your question.
In your second example, although unstated in the CSS, .center
has the default positioning and the default display for a <div>
:
.center {
position: static; // by default
display: block; // by default
background-color: lightcoral;
}
That means it completes displaying itself within the vertical flow, as a statically positioned, block-level entity.
Then, after this element completes displaying itself (within the flow), the next element in the vertical flow is .left-box
.
.left-box
begins displaying itself at the first available point within the vertical document-flow.
But the top of .left-box
can't be any higher than the bottom of .center
because the latter has already completed positioning and displaying itself within the vertical document flow.
In your first example, .center
also begins at the first available point within the vertical document-flow... but, by contrast, this first available point is no lower than where .left-box
begins.
Why not? Because, as a floated element, .left-box
is absent from the vertical document-flow.
This means that .center
may essentially ignore .left-box
and display itself within the vertical document-flow precisely where it would have displayed anyway if .left-box
didn't exist.
Spacing out floating elements with both sides of a container
Here is one way of realizing your layout using inline-blocks instead of floated elements.
First, to the .blue
containing block, set the following CSS properties: text-align: justify
and line-height: 0
.
Second, for the .red
child elements, remove the float
property and add display: inline-block
.
The result is that your .red
elements are now inline and will be spaced evenly in a line within the width of the .blue
container. Since you hard-coded a nice value of the width for .blue
, you will get the horizontal spacing that you want between the .red
blocks (no need to set a right margin).
The remaining issue with text-align: justify
is that the final line will not stretch to fill the full width (this is how the justify setting works in order to prevent short lines from being stretched out in a ugly fashion).
To work around this, add a pseudo-element .blue:after
which is an inline-block of width 100%. This will force a new line to be created after your red blocks, and the result is that all the red blocks are left/right justified.
The line-height: 0
on .blue
and vertical-align: top
on .blue:after
take care of any extra white space at the bottom due to line leading (space above and below the baseline of the text).
.blue {
margin-top: 10px;
background-color: #00A2E8;
height: auto;
overflow: auto;
padding-bottom: 10px;
text-align: justify;
line-height: 0;
}
.blue:after {
content:'';
display: inline-block;
width: 100%;
vertical-align: top;
}
.red {
background-color: red;
width: 50px;
height: 50px;
display: inline-block;
margin-top: 10px;
}
<div class='blue' style='width: 110px'>
<div class='red'></div>
<div class='red'></div>
</div>
<div class='blue' style='width: 110px'>
<div class='red'></div>
<div class='red'></div>
<div class='red'></div>
<div class='red'></div>
</div>
<div class='blue' style='width: 170px'>
<div class='red'></div>
<div class='red'></div>
<div class='red'></div>
<div class='red'></div>
<div class='red'></div>
<div class='red'></div>
</div>
Related Topics
Why Does a Diamond with a Questionmark in It Appear in My HTML
CSS Filter:Invert Not Working with Background-Color
Is There a CSS Selector for Selecting an Element Futherup in the HTML
CSS Two Columns of Lists - Responsive Merge into One Column
Aligning Two Flex Items: One to the Top, the Other Centered
Making All Images Appear with the Same Height in Bootstrap
How to Vertically Align a Div Next to an Image
Removing Border Style Changes Page Layout
Get Input Type=Text to Look Like Type=Password
How Remove Border Around Image in CSS
Why Should One Add Id to Their HTML Tags
Bash Script to Convert from HTML Entities to Characters
Image Flex Item Does Not Shrink Height in a Flexbox
How to Make a 2 Column Layout Where Items Starts from Top to Bottom (Not Left to Right)
Responsive 2-Column CSS Layout Including Sidebar with Fixed Width