Why do block elements go behind a float and inline go around? - html

I am finally starting to understand floats in CSS but I am stuck on one part.
I understand floating an element takes it out of the flow of the document so elements after it would render 'underneath' it as it is not visible to them.
However I am having difficulty understanding why inline elements are aware of the float and flow around it if it has been taken out of the document flow?

Why inline elements flow around float?
From MDN:
The float CSS property specifies that an element should be taken from the normal flow and placed along the left or right side of its container, where text and inline elements will wrap around it.
float origins:
The practice of flowing text around an image goes back a long, long time. That's why the ability was added to the Web starting with Netscape 1.1, and why CSS makes it possible using the property float.
Complex Spiral Consulting
So float was designed to solve this particular problem:
Consider This figure:
And the markup structure that produced it:
<p>
...text...
<img src="jul31-03-sm.jpg" height="200" border="0" class="picture">
...text...
</p>
<p>
...text...
</p>
The floated image is sticking out of its containing element. We can see this more clearly by adding borders to the paragraphs:
Using float makes it possible for the paragraphs to ignore the image, while the text wrap around it.

There are rules governing the relationship between floated elements, block elements and line boxes.
These rules are defined in the CSS Visual Formatting Model.
In particular, note this section from the specification:
The IMG box is floated to the left. The content that follows is formatted to the right of the float, starting on the same line as the float. The line boxes to the right of the float are shortened due to the float's presence, but resume their "normal" width (that of the containing block established by the P element) after the float.
In other words, block boxes, such as a p, will flow behind the floated element. But the line boxes in the p, which wrap the text, respect the presence of the floated element. These are just the rules, as defined in the spec.

Float element is designed so that it always floats to left or right side of the parent element. But it doesn't cover the content part. Content part always follows float element (Like you said).
Basically, there is a quite small difference between display:block and display:inline.
display:block represents block or lets say container which wraps a complete parent div horizontally and has margin and padding properties.So, it may behave as a parent container, and so float covers its part.
display:inline subjects to content not a container. It dosen't have a padding or margin properties so it is considered to be a part of a content. That's why it follows float element. Even if you add some content in display:block element, there you will see that content is following float element.

Related

Why is the display property of floated elements said to be block level?

Why do we say that the display property of floated elements may change to block level, instead of saying inline-block, because it starts taking the space according to the content it wraps?
inline-block means inline level, block container.
inline-level elements participate in the layout of a line (or multiple lines). This affects line spacing and the vertical alignment of other elements in the same line.
Floated elements do none of that. The participate in block formatting contexts, not inline formatting contexts.
That is the purpose of float. found some information in here
The float CSS property specifies that an element should be placed along the left or right side of its container, allowing text and inline elements to wrap around it. The element is removed from the normal flow of the web page, though still remaining a part of the flow (in contrast to absolute positioning).
Also
when an element is floated, it is taken out of the normal flow of the document (though still remaining part of it). It is shifted to the left, or right, until it touches the edge of its containing box, or another floated element.

CSS Non-Positioned Boxes

So, I am reading through the CSS spec on W3 site, and I came across the use of the word "non-positioned" which I am having a hard time picturing. Please see below use.
Since a float is not in the flow, non-positioned block boxes created
before and after the float box flow vertically as if the float did not
exist. However, the current and subsequent line boxes created next to
the float are shortened as necessary to make room for the margin box
of the float.
My question is/are,
what is a non-positioned box in CSS context? Is it a box in normal-flow? Or a box that does not have style property position explicitly set?
What does the first paragraph up there mean?
I mean what does the spec. mean by the
"current and subsequent line-boxes created next to the float are shortened to make room for the margin box of the floated-box"
when the floated-box is OUT-OF-FLOW?
Thanks in advance for your answer.
Three paragraphs above the one you quote, it says "The following is an introduction to float positioning and content flow; the exact rules governing float behavior are given in the description of the 'float' property."
So it is worth noting that the language used in the quote is not as precise as is usually is in the CSS spec.
what is a non-positioned box in CSS context?
Here it means a box of an element whose position property has the value static That is, it always true for position:static elements. However, the quote does not imply that it is always false for boxes with other position values.
Is it a box in normal-flow?
It's similar. Normal flow contains boxes that are position:static and position:relative and which are not floated elements.
Or a box that does not have style property position explicitly set?
Not necessarily. Elements are position:static by default, but could be explicitly set to static too.
what does the spec. mean by the
"current and subsequent line-boxes created next to the float are shortened to
make room for the margin box of the floated-box"
In a (say) div element, the text is laid out as a stack of line boxes. If there is an immediately preceding float, The <div> element will go "behind" the float. You can see this by, say, reducing the opacity of the float and putting a background-color on the div. But the text won't go behind the float, because the text goes in the line boxes, and the line boxes avoid the float. See this jsfiddle.

Floated queries

Consider the following code:
<div style="width:250px;background:red;">
line1
<div style="width:auto;background:green;margin-left:10%;margin-right:10%;" >
line2
</div>
</div>
and its results:
The above is absolutely understandable to me.
Now, this code:
<div style="width:250px;background:red;">
line1
<div style="float:left;width:auto;background:green;margin-left:10%;margin-right:10%;">
line2
</div>
</div>
and its results:
I cannot explain two things. First one: why does the inner div change position? Since floating does not affect previous elements, I'd expect text "line1" would not wrap next to green div! Second one: Float property does not accept width:auto? Why green div shrinks?
Thank you
A document flow refers to block elements rendering in a vertical direction, inline elements rendering in a horizontal direction, and all elements rendering in the order they are encountered.
Excerpt from w3.org - Floats and clearing
<p>This is a very simple document.</p>
<p>It consists of <em>two</em> paragraphs.</p>
Here is a screen shot of that document with an overlay that shows the two block boxes generated by the p elements and the inline box generated by the em element.
Float alters the way that the element is rendered in the document flow. Unlike position absolute, it will not entirely remove the element from the flow. It essentially makes it similar to an inline block element with the caveat that it will "float" over other non floated elements in the direction indicated as far as possible.
As a result, the line2 element does not cause a new line, and takes precedence in rendering over line1. Because of this you end up with a line2 element coming before line1.
As for the width, since line2 is now inline-ish its width is just to contain the content. When auto is used, it has no affect on this.
However, there is a caveat. If width:200px; were used on line2 then that would make the float be placed on the next line because that was "as far left as possible" since there was not enough space to float a 200px element (+20% for margin) in the previous line. Because line1 was already there, and with 200px and 20% margin of the containing block (50px), line2 would not be able to fit on the same line.
fiddle for image

alignment of a div

What is the default behaviour of a div?
I noticed that even if a put a width for a div let's say 100px,
if i put a 2nd div with the same width will put it on the second line.so by default doesn't matter the width. it puts it on different lines?
in this case i understand the need of float.
I thought that any element i put in a html page,they will be side by side unless i add a break element or paragraph or something with that role.
Or maybe i do not use it correctly the div for this kind of alignment,but i really want to
clarify this for good.
A div element is, by default, display: block.
This value causes an element to generate a block box.
The rendering of them is described here
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'.
Block-level boxes are boxes that participate in a block formatting context.
and then here
In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block.
To stop this kind of rendering, you can use float to cause block level elements to bubble up beside each other. You can also modify the display property of the div.
Divs are block-level elements which mean they stack...like blocks. Although it sounds reasonable that since the width would allow them to fit side-by-side without a float, this is not how they are designed to behave.
If an element is an inline element as opposed to a block, its behavior is to fit side-by-side. You can force this behavior on a div if you would like by tying the two ideas together. You can do something like:
<div style="display:inline-block"></div>
This will allow the div to maintain its other block properties but allow it to fit inline as text and images would and, if this the your desired goal, avoid the use of float.
The DIV by default takes 100% of the screen, even if you set it width the space on the right cannot be occupied by anything.
Try this:
The way to have two div on the same line would be to make them float:
<div style = 'float:left;width:500px;background-color:red;color:white;'>Hey</div>
<div style = 'float:left;width:100px;'> There</div>

Shouldn't floating an inline element create three block level elements?

Here's my doubt. If I float an inline element, since it's display is automatically set to block, and since siblings of block level elements have to be themselves block level elements(anonymous ones if they must), shouldn't in the example below, the first and second anonymous blocks be placed on separate lines as block level elements do by default?
<p>
This will be the first anonymous block, <span style="float: left;">this will
be the span</span>, and this will be the second anonymous block.
</p>
See my demo: http://tinkerbin.com/5niDbThT
Notice that when I directly set the display to block on the span of the second paragraph, three different block level elements are created - just as I imagined it would happen when floating.
My guess is that floating is simply an exception that doesn't trigger the effect. But you tell me ;). Thanks in advance!
Floats take the object out of the document flow which is why it shows up as it does.
Inline-block: "The element is placed as an inline element (on the same line as adjacent content), but it behaves as a block element"
You can also "clear" dom elements which pushes the element past the floated object. Most commonly used in a layout with a main area and a right/left column side by side.
So I thought about your question and the implications for a while and this is the conclusion I've come to:
So according to the W3 CSS spec, http://www.w3.org/TR/2011/REC-CSS2-20110607/visuren.html#floats, "Content flows down the right side of a left-floated box and down the left side of a right-floated box." So what the first example span in your tinkerbin is doing is perfectly normal; it's what is supposed to happen when a floated element comes in contact with any content. Actually in your tinkerbin you didn't set the span with display:block as float:left, so it just created a scenario where the other elements have to be treated as block-level, as you mentioned.
If you do apply float:left to span-2, you get the same result as span-1.
I edited your tinkerbin and put in a div structure: http://tinkerbin.com/NoOqLU4O which uncovers additional weirdness. It seems to treat text before the div as a block but text after it as content. Who knows?
Bottom line I think that you're right, floating is an exception that doesn't trigger the effect because it's hard to put a finger on what exactly is "content that should wrap to the float" when your float itself is content..