Why does overflow property impact element size and flow? - css

I've stumbled upon some behavior in CSS that is confusing to me. Let's say there are two block elements, first of them floated to the right (jsfiddle):
If the overflow property is set to hidden on the non-floated element, that element is shrunk in order to accommodate for the floated element width jsfiddle:
I actually don't have a problem with that, but I would like to know why that is happening. What I do have problem with is the following case in which after the overflow is set to hidden, width of the non-floated element is set to 100%. I tested this in IE9, Firefox 14, Opera 12, Chrome 20 and Safari 5 on Win7, and all of them except Firefox show (jsfiddle):
What I wanted and expected, and what Firefox shows, is the same as in the first picture above. So, can anyone shed some light on why all this is happening?

According to definition "If the container element is itself contained by something else, the floated div will sit on the right margin of the container."
Case 1: The .container is covering the total space available. The .content is taking all the space except the .float(the .content is not of shape rectangle here), that's what floating is. Its actually overflowing to cover the space. Its the default behaviour.
Case 2: Now you tell the .content to hide the overflow. So it hides the overflow it was earlier doing as a default behaviour.
Case 3: You tell the .content to take the full width of the parent, i.e. .container, so it ignores the overflow:hidden and just expands to fill the space.
If you are wondering the weird behaviour of overflow:hidden, check this ARTICLE

Related

Why does Safari refuse to render a div with hidden overflow at full width in presence of floats? [duplicate]

I have set up some divs for my layout, a main div and a menu div.
They look perfect in Firefox, but for some reason, Chrome and Safari get messed up.
For some reason the width of the div gets smaller when overflow:hidden; is added to the CSS. I need overflow:hidden; though, because I have other floats inside the main div. You can see the example here:
http://jsfiddle.net/kR7rs/2/
It shows up fine in Firefox, but in Safari and Chrome, there's a margin on the right side of the div as well.
Removing the margin from main seems to fix it:
http://jsfiddle.net/kR7rs/3/
What I think it happening is that when overflow:hidden is set, the entire element wraps around the floats instead of the text within the div. So this gives the result in the fiddle. Then if you set a margin on it also, the width is decreased further by the left padding.
Kind of seems like a bug.
(Don't have FF right now to test it and see if it breaks it for FF.)
Move overflow:hidden to #wrapper. That fixes it, but doesn't explain why.

Cross-browser Issue: Min-height and collapsing margins

As you can see in this simple example:
<div id="minheight">
<p id="margin">Paragraph with a margin</p>
</div>
<div id="sibling">Sibling div</div>
#minheight {
min-height: 100px;
background: red;
}
#sibling {
background: blue;
}
http://jsfiddle.net/peterbriers/B43th
There is a difference between Chrome (35) and Firefox (29) in how it handles the collapsing margins on a block with a min-height that is larger than the child's margin.
I tried to fully understand the specifications: http://www.w3.org/TR/CSS2/box.html#collapsing-margins , but I'm still unsure which browser handles this correctly. I would say Chrome is in the wrong, but Safari (7) does it the Chrome way too.
Which browser is correct, and how can I file a bug for the one that isn't doing it the right way?
BTW: I'm not asking any fix by adding new block formatting context (adding overflow property)...
OK, so this seems to be a very peculiar case.
If you change min-height to height, the gap disappears in Chrome. Not only does Safari behave the same as Chrome, but so does IE. Firefox's behavior is unique to itself, and its behavior does not change when you make that adjustment to your CSS. This should come as a surprise, as you would not expect min-height and height to behave any differently in your given scenario.
However, the spec has something interesting to say about min-height with respect to margin collapsing:
The following algorithm describes how the two properties influence the used value of the 'height' property:
[...]
These steps do not affect the real computed values of the above properties. The change of used 'height' has no effect on margin collapsing except as specifically required by rules for 'min-height' or 'max-height' in "Collapsing margins" (8.3.1).
Because you have not specified a fixed value for the height property on the same element that has a min-height, the computed value for height remains the default auto, even though the used value is floored to min-height.
Therefore the following text from section 8.3.1 applies, and the margins between the block box and its child should collapse as a result, irrespective of min-height:
Two margins are adjoining if and only if:
both belong to vertically-adjacent box edges, i.e. form one of the following pairs:
...
bottom margin of a last in-flow child and bottom margin of its parent if the parent has 'auto' computed height
Note that it goes on to list some scenarios in which margins may or may not collapse:
Note the above rules imply that:
...
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.
... but it does not state what happens when the block box has height: auto and a non-zero min-height.
Based on this, it would be safe to assume that the spec should be interpreted as I am doing. Therefore it looks like Firefox is not behaving quite correctly, and all other browsers are following the spec to the letter, despite what one might expect from the behavior of height and min-height.
You can file a bug for Firefox here, although it looks like the developers have already made themselves aware of this issue.

Floated elements inherit top margin when the containing element has a clear property

I've stumbled across a bug with floated elements within a container when that container uses clear: both; (or left/right). In Chrome (not Safari), the first floated element is positioned correctly, but all subsequent elements appear to inherit the top margin of the parent element, shifting them out of line.
Here's the problematic code: http://jsfiddle.net/peterjmag/3zJey/1/
Try the toggle link to see the difference. Also, try various values for margin-top on #product-listing.
For those of you using other browsers, here's what the fiddle looks like for me (in Chrome 25.0.1364.160 for Mac):
Why does clear: both; cause this behavior in Chrome? According to the CSS 2.1 spec, the clear property should only affect floated elements that appear earlier in the document, not within the targeted element.
(Of course, I know there are other more optimal ways to clear previous elements in the document which would not require a clear property on the container div—I'm simply trying to understand why this happens.)
It appears that this is indeed a Chrome bug: Issue 178134: Floated elements render incorrectly when parent element has a clear property + a top margin. According to that report, Chrome 27 and above are not affected.

Different rendering from Chrome and Firefox when having floated children in a floated div with no width.

I've set up a test here
http://jsfiddle.net/WZyF7/11/
Firefox seems to differ from Chrome and IE7-9 on how to calculate the width. Instead of giving the content as much width as it needs, it makes the div as wide it's widest child element. This stacks the elements vertically in FF, while horizontally in other browsers.
Is there any way to make all browsers handle this the same way without setting a width to the parent element or using JS? And does anyone have information on exactly how this is calculated across browsers? (width:auto; ? )
The relevant spec bit is http://www.w3.org/TR/CSS21/visuren.html#floats where it 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. If necessary, implementations should clear the said element by placing it below any preceding floats, but may place it adjacent to such floats if there is sufficient space. They may even make the border box of said element narrower than defined by section 10.3.3. CSS2 does not define when a UA may put said element next to the float or by how much said element may become narrower.
And the part in http://www.w3.org/TR/CSS21/visudet.html#float-width which says:
If 'width' is computed as 'auto', the used value is the "shrink-to-fit" width.
and following. Note that the actual computation of preferred width, which is what matters here, is not all that well defined. So basically, per spec behavior in this situation is undefined.
In any case, what's happening here is that Firefox is giving the overflow: hidden block the width it should have per section 10.3.3 and then clearing it past the float, while Chrome and IE seem to take the "they may even" path. And in particular, it's assuming it will do that when computing the preferred width of the parent.
All that said, I think the Firefox behavior is more correct in this particular narrow case: your "container" is 400px wide. The "parent" has 20px of horizontal padding. The "floated" is 300px wide. The "content" has 20px of horizontal padding. That leaves 60px of width for the text inside "content", but the longest word ("available...") is about 70px wide with my fonts. In Chrome, for example, the only way "content" fits next to the "floated" is because the right padding of the "content" disappears entirely. Firefox will do the same thing if you give a fixed width to the "parent" here.... but then you're forcing a width, instead of asking the browser to pick a reasonable one via the shrink-wrap algorithm, of course.
Your best bet here is to just give the "parent" a specific width if you want it to have that width, instead of relying on shrink-wrapping to produce a width that's actually too small for the content.

CSS word-wrap causes whitespace overflow after div

I'm using the CSS word-wrap property (set to break-word) to display a single no-spaced string in its entirety within a div element of fixed width and variable height. The div element itself is within a table cell <td>. The word break works as expected, breaking the word at the defined fixed width. However, in IE9 (with IE7 document standards), there appears to be some extra space after the div, causing the table cell to extend in width (not desired). The div width itself appears to be correct, as specified by its CSS. I used borders around the div and table cell to verify. I've tried explicitly setting the table cell width (and max-width) but neither approach works. This behaviour is not observed in Firefox or Chrome.
Edit: Added sample code here. The problem only occurs with IE (Browser_Mode=IE9; Document_Mode=IE7).
Apparently the td is making room for the full length of the word, as though it weren't breaking. You can prevent this by setting overflow: hidden on the div.
jsFiddle: http://jsfiddle.net/gmDpe/6/
I came across a similar problem once.
Have you tried to use table-layout : fixed on your table element ?
table-layout is a very little known but widely supported property which can be quite helpful in cases like this.

Resources