CSS block-level vs inline container issue - html

Here is the demo http://jsfiddle.net/aTBWh/
the container is id(div) meaning it inherits a display:block value from the browser, the two div's inside this container are classes. they both have 200px and 300px while the main container has 600px width, so I thought when I floated one of the classes to the right, it should only consume 300px from the whole container meaning the two div's should fit inside the container without one appearing above the other. there is no clear:both attribute.
if the container is an id, with 600px, then the classes nested inside it (specially when one is floated to right, they should fill the container.)
in a nutshell why is the green div class out of the container when it can clearly fit there, and it is floated to the right? I don't understand this problem.
codes:
css
#content_canvas_container{
background:#CCC;
min-height:200px;
border:1px solid red;
width:600px;
}
.red{
width:200px;
background:red;
height:140px;
}
.green{
width:300px;
background:green;
height:140px;
float:right;
}
/*PROPERTIES*/
.w90{width:98%}
.m_auto{margin:auto; border:1px solid black}
html
<section id='content_canvas_container'>
<div class='w90 m_auto'>
<div class='red'> red </div>
<div class='green'> green </div>
</div>
</section>

What you are seeing is expected behavior.
The reason this is occurring is because the red div element is a block level element by default. Thus, in its current state, it will always appear on a new line regardless of whether it has a defined width or has floating sibling elements.
By floating or absolutely positioning an element, you are essentially removing it from the flow of the document, rendering display:block ineffective. Therefore you can solve this by either floating the red div element, or adding display:inline-block to it. (example)
jsFiddle example
.red {
width: 200px;
background: red;
height: 140px;
float: left;
}

That happens because when you set a float to a box, it moves to the left or the right of the container (according with other complex rules, of course), but it's vertical offset from the top of the container can't be smaller than it would be if it wasn't floated.

The browser is making a decision based on what you are telling it to do.
You haven't specified a float on the red div, so it remains in flow and acts as a normal block level element does i.e. "push everything after me to the next row".
You then tell the green div to float right in it's container, so it shifts over to the right.

Using float:left will allow other elements to wrap around it. (CSS-float)
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. A floating element is one where the computed value of float is not none.
.red{
float:left;
}
Fiddle
To understand why other elements won't wrap around your div by default, read up on block-level elements here.
"Block-level" is categorization of HTML elements, as contrasted with "inline" elements. Block-level elements may appear only within a element. Their most significant characteristic is that they typically are formatted with a line break before and after the element (thereby creating a stand-alone block of content). That is, they take up the width of their containers.
By default your div elements are block-level until you specify otherwise. The link I referrenced gives a list of all the elements that are block-level by default.

This happens because DIV are block-level elements, it means they begin in new lines. In your example when floating .green to the right, .red element still takes 100% of horizontal space, and .green takes now 300px but it is pushed down because as a block level element it belongs to the next line. To avoid this behavior, you must transform block elements into inline elements.
So in this case if you would like to float .green to the right, DIV elements within the parent wrapper should be rendered as inline blocks instead of independent blocks, just adding this rule:
.m_auto div {
display: inline-block;
}
Cheers.

Related

If Inline box is relative positioning, then what is its block-level box affected by?

source spec: Anonymous block boxes.
I'm confused about this sentence.
When such an inline box is affected by relative positioning, any resulting translation also affects the block-level box contained in the inline box.
I don't know whether the "relative positioning" is the general meaning, I mean it can be absolute or fixed, and other properties of display, e.g, inline-block.
Let's see examples.
I know DIV broke the line box, but position: relative seems useless, I can remove it directly.
.father {
position: relative;
border: 1px solid red;
}
<span class="father">
<div>Hi Wick</div>
</span>
But, If I modified relative to absolute, I knew the line box wasn't "broke", so border worked normally. If I added the inline-block property of display, the result is the same.
.father {
position: absolute;
border: 1px solid red;
}
<span class="father">
<div>Hi Wick</div>
</span>
Also, what does any resulting translation mean? I know some behaviors may change containing block, so they will be affected by their descendants. I'm not sure whether it is about the containing block.
Therefore, I need some examples!
A <span> element is inline, which means it has no "box" around it to apply a border to. It's treated the same as a line of text with no container. Imagine it as a horizontal line where the center of each letter inside it is placed on that line. Applying position: absolute; to a <span> causes it to be treated the same as if it was display: block;, which is why the border property works on it then.
In your first example, the inner div is a block level element inside an inline element. If you applied a border to the div, you'd see it stretches across the width of the container to fill the space horizontally. Since the parent span is inline, the border doesn't show like you want it to, but the height of the child div at least gives some level of "size" to the span, if only vertically.
Also, "any resulting translations" just refers to CSS properties that move the element on the screen, such as left, right, top, bottom, or transform: translate();.

Why non floating children of floating container div don't float

https://jsfiddle.net/0k02qsjw/1/
.left1 {
background-color:red;
width:100px;
height:100px;
float:left;
}
.left2 {
background-color:blue;
width:100px;
height:100px;
}
//left3 left4 similar to left2. fiddle
<div class="left1">Div1</div>
<div class="left2">Div2child</div>
<div class="left3">Div3</div>
<div class="left4">Div4</div>
I'm learning float and clear in css and am stuck on one problem. Float works as expected in the above example when I float each div individually. When I float left1, left2 moves up as expected. But why is it that children on left2 not move up?
I understand that floated elements are out of flow -> may that's why.
If so, why does overflow:hidden on left2 work as if left2 was floated(see below).
https://jsfiddle.net/0k02qsjw/2/
I need help in understanding what is happening in this case. This could be a duplicate of
Floating elements within a div, floats outside of div. Why?
But i don't find any answer to my specific question there.
https://developer.mozilla.org/en-US/docs/Web/CSS/float
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.
So when you float an element, other block elements don't float around it - the inline and text elements in a neighboring element float around it.
If you're floating .left1, the content in .left2 doesn't go up and wrap around .left1 because they're the same width. .left2 needs to be wider than .left1 for it's inline and text content to be able to wrap around .left1. You can see this by setting the width of .left2 to 200px. https://jsfiddle.net/0k02qsjw/3/

Confusion about negative margin of float none and float left elements

I feel like CSS is much harder and confusing than C++ therefore I have few questions.
Consider following html body
<div id="mydiv1">12345~~~~~~~~/</div><div id="mydiv2">+_______67890</div>
And CSS
#mydiv1 {
float: left;
background-color: red;
margin-right: -30px;
}
#mydiv2 {
float: left;
background-color: blue;
}
which looks like this (in my latest Chrome)
which makes sense to me because second div is floating and it floats over first div.
On the other hand if I remove float property from mydiv2 only content moves but background box stays in the same place.
1) Could you please explain why ?
Now I'll remove margin and float, and add width to both divs making having CSS
#mydiv1 {
background-color: red;
width: 220px;
}
#mydiv2 {
background-color: blue;
width: 240px;
}
It will expectantly look like this
But if I add float: left to #mydiv1 it suddenly looks like this
2) Why did second div become twice as high ? I checked it by setting z-index of first div to -1.
PS. I've done tutorials on CodeAcademy and read float/margin-related articles on smashingmagazine.com. Sadly it didn't made everything crystal clear. If you guys can suggest online resources or book that would have explained these questions to me I'll appreciate it a lot.
<div> is a block-level element so it naturally fills the width of the container it's in. It makes its neighboring elements go above/below it, but not beside it.
Now, when you apply float to a block-level element, it no longer fills the width of the container, its width will be that of its contents. It also loses the ability to force its neighbors to go above/below it.
Note:The tricky bit is that the container holding the floated elements will not have a proper height because the floated elements are no longer part of the regular flow of content. (Here's how to get around it: http://www.quirksmode.org/css/clearing.html)
Regarding the last part of your question, if a floated element, eg. #mydiv1, is beside a block-level, eg. #mydiv2, then the block-level element wraps or flows around the floated element. It's one of the ways people can get text to wrap around an image in a news article.
When you remove the float from div2 it goes behind the floated div1, because floated elements does not take any height from it's content. You can say it's going out of the vertical flow of elements. However, it still take horizontal space from content. So the result is as expected here, once you "know the rules".
This should also explain the double height in your other example.
Here is a great article from css-tricks.com
I hope that helps!
If we don't give either float or width to any block level element like div then it occupies the entire width of the container.
Instead of float you can give some width and display: inline-block. This display property will display content inline and behaves like a block level element.

Why do floated elements appear before non floated element, even if they come after it in the markup?

I thought that text will flow around a floated element if the text follows that element in the markup. Why then does the following example produce the shown result?
Here is the HTML:
<div class="float block red">Red</div>
TEXT BETWEEN RED AND BLUE
<div class="float block blue">Blue</div>
<div class="float block green">Green</div>
And the CSS:
.float{
float: left;
}
.block{
width: 50px;
height: 50px;
}
.red{ background-color: red; }
.blue{ background-color: blue; }
.green{ background-color: green; }
And this is the result:
Why isn't the order on screen: Red, TEXT BETWEEN RED AND BLUE, Blue, Green?
Thanks
“A floated box is positioned within the normal flow, then taken out of the flow and shifted to the left or right as far as possible. Content may flow along the side of a float. [...] When a box is taken out of normal flow, all content that is still within normal flow will ignore it completely and not make space for it.”
Source
It's because you're floating the elements left. You're essentially saying that those elements will be as far left on the page as they can be, relative to other floated elements. Your text is not floated, and is thus relative to the right-most, left-floated element. Does that make sense?
To achieve your desired result, just put the text in a DIV, SPAN, etc. and float it left also.
There are two types of elements in CSS: Block level and Inline elements. These elements, and their positioning, are governed by a concept known as the flow.
Block-level elements have breaks before and after them, inline elements do not. While this is extremely over-simplified, these are the basic rules that govern flow in CSS.
Elements that are given position:fixed and elements that are given a float attribute are removed from the flow in the normal sense, with the additional caveat that inline elements and text will wrap around the floated element.
If you can imagine a floated element as a box that physically lifts itself off the ground, flies to the left or the right until it can go no further, and then plops itself back down on the ground, you've got the right idea (think Terran bases in StarCraft). The floated element blows right by your text, and then your text repositions itself to wrap around the floated stuff once it has "landed".
Floats always position themselves in relative to other floats.
The exception to this is when an element has a clear stuck to it. The CSS clear property basically says that any block level element will either permit floats to be on one or the other side, else kick the floated element down to the next line. It's actually a little more complicated than that, you should check out the MDN article on Clear.

When should floated HTML elements be cleared exactly?

Could anyone explain when should the floated elements get cleared?
I have noticed sometimes when I make something in HTML, and I don't clear them, it still all looks good!
Also can overflow:hidden be used as a replacement for clearing?
Look at this example:
<html>
<head>
<style>
.a { background-color: red; overflow: hidden }
.floated-left { float: left; width: 100px; height: 100px; background-color: blue; }
</style>
</head>
<body>
<p>div with class a, that does have overflow:hidden:</p>
<div class="a">
<div class="floated-left">Hi,</div>
<div class="floated-left">Mom!</div>
</div>
<p>i didn't clear anything</p>
</body>
</html>
Here I didn't clear the floated divs, but set overflow:hidden for the .a class and the <p> below appeared in normal element flow.
However, if I removed overflow:hidden from the .a class, <p> gets displaced.
Please explain!
Thanks, Boda Cydo.
For block-level, non-replaced elements, when overflow isn't set to "visible" and height isn't "auto", the element's height depends on its descendents (CSS 2.1 § 10.6.6). Thus when you set overflow: hidden on .a, it stretches to contain the floated descendents. The <p> is below .a, so it's below the floats.
Without overflow: hidden, .a doesn't contain the floated children; its calculated height is 0. The <p> is still below .a, but not the floats. The floats push the inline content of <p>, as floats are wont to do.
Try putting borders around .a and paragraphs to more clearly see the difference.
overflow: hidden should be used as a replacement for clearing divs whenever it can be, which is most of the time.
IF you need to float the elements around an tire block as unit and the containing element needs to expand vertically to the height of whichever is highest. Otherwise the text/inline elements of the non-floated adjacent elements will flow around the float. If this content ends up being taller than your float then youll be ok... the container will expand. If however the floated elemnt is taller, then youll need to clear it if you want the container to be as tall as the float.
Just as I replied in your other post When should overflow:hidden be used for a <div>? this is because the child elements of the a div throw the margins out of bound for a when overflow is anything other than visible. When overflow is visible, a technically stops at the boundary of the div for "Mom!". When it is other than visible (overflow, scroll, auto), the boundary continues until it reaches the boundary of its own parent (in this case the right edge of the browser). The new block element may not begin until it has space to go in. Effective when overflow is visible, it may begin directly after the margin boundary of the last floated div. When it is other, it must wait for a full break in the div.