IE7 ignoring margin in a div following an absolute positioned div - html

I have two divs inside a container, the first one has absolute positioning. In ie7, the second div apparently ignores the top margin. Padding seems to work fine, but for visual reasons I have to use margin.
I know the culprit is the absolute positioned div because if i remove it the following div works fine.
This is only happening in ie7 (not even in ie6).
Help!
Edit: I just found a solution which consists of giving the parent div padding-top just for ie7. So I would just like to know why does this happen, and if there is one, a cleaner solution, but I dont need more dirty hacks..

This is what we call margin collapsing. You could try to positioning the second div too.
You could find more information about margin collapsing.
Just check the conditions below if you have any of them in your code before start reading the whole article.
BODY elements never take part in
margin collapsing, since they are
considered magical, which means
sometimes a strange gap does not show
up in Internet Explorer when it does
in other browsers, when the collapse
happens with the top of the BODY. This
is usually easy to solve; just prevent
the margin collapse for the other
browsers, and it works in Internet
Explorer too. (Note that the HTML
element's margins never collapse in
any browser, this is correct
behaviour.)
In rare cases, margin collapsing where
an inner element has a bottom border
and an outer container has a bottom
border, can cause the background of an
intermediate element to spill into the
container in Internet Explorer.
The more problematic bug is caused by
Internet Explorer's strange hasLayout
behaviour. This is a fundamental bug
in Internet Explorer 7- and affects
several other things as well, but this
article will only deal with margin
collapsing. Setting certain styles on
an element makes it "have layout" (a
concept unique to Internet Explorer,
and not compliant with any standards).
The most common style that causes a
problem is width. When an element
hasLayout it suddenly assumes a
minimum height of 1em, and if set to
something less in Internet Explorer 6,
such as 0.5em, it still uses 1em.
An element has layout when one of the following conditions is true:
It has a width and/or a height specified
It is an inline-block (display: inline-block)
It has absolute positioning (position: absolute)
It is a float (float: left, float: right)
It is a table element
It is transformed (style="zoom: 1")
Height usually does not cause a
problem, since setting height will
prevent collapsing in other browsers
anyway. However, triggering hasLayout
on a nested element where the parent
has prevented margin collapsing using
borders or padding, can cause margins
to disappear, or to collapse through
the parent irrespective of the padding
or borders. Generally, hasLayout is a
mess, and it is best to avoid it in
places where margins are critical.
I hope this will help you to go through with your problems.

In my case nothing above helps. I use the additional DIV between these elements. This additional DIV has clear: both, flot: none etc. See http://starikovs.com/2010/12/24/ie7-margin-top-and-absolute-pos-element/ for more info.

I used position:static; on the larger div (with position:relative on the content inside) on the ignored margin for an IE7 fix. The smaller left hand side column remained position:absolute. This was used on a Jquery vertical tab.
http://code.google.com/p/jquery-vert-tabs/downloads/detail?name=jQuery%20Vertical%20Tabs%201.1.4.zip&can=2&q=

Related

Adding margin-bottom to child of a min-height container has strange effects [duplicate]

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.

Weird margin differences between Chrome/Safari and Firefox

I recently designed a website (http://willryan.us/typefun01), mainly using Chrome while coding to test. I recently noticed that there are some weird things happening at the end of certain sections, (the gap after History, the overlap of Styles onto Anatomy).
I have a css reset in my stylesheet (not sure if that has anything to do with this), and I can't figure out what's causing this, and how to get the site to look like how it does when viewed in Chrome
The gap after History is due to:
#historyWide {
margin: 250px 80px 75px;
}
It could be remedied with:
div#content > div {
overflow: hidden; /* or auto */
}
You could also move the large top and bottom margins of elements inside the child divs of #content to padding on the child divs themselves. Anything will work as long as it's all contained by those child divs.
You're simply seeing the different ways that browsers handle imperfect layout.
If you want to avoid the gap after History you would want to use a padding in historyWide instead of a margin; the margin pulls aways elements while padding makes them bigger
On anatomy what's happening is that you're using the property "top" to modify #styles, this will move the element but the parent will reserve only the original space for the element. You will be better off working with margins and padding than with "top" if you have to keep a relation between the elements.
Lastly, i woulnt position elements with margins like you did with #stylesMono. I think you could better work with paragraphs to keep keep the vertical position and, from there, working with floats, margin and padding in the scope of the "p".

Chrome ignoring static width and fitting to content instead, works in all other browsers

The issue I'm having can be found here:
http://jsfiddle.net/boblauer/5uVrK/
If you look at it in Chrome, you'll notice that when you scroll to the right, it stops immediately at the right edge of the last green box. However, in FF and IE (haven't tried others), it will correctly scroll a bit past the last green box.
Since .lane-container has a width of 2000px and the boxes should take up a width of 1700px, there should be 300px extra to the right of the last box, but in Chrome there is not.
Any ideas on why Chrome behaves differently than the others, and how I can work around it?
Setting the display to inline-block instead of float: left fixed the issue for me. Floating block level elements takes them out of the dom flow. That doesn't really explain why this doesn't work, but this is a workaround. I always prefer inline-block over floating left.
Edit
After some more jsfiddling, it seems chrome isn't showing the container div's full width because it's empty. As soon as you add a border around lane-container it works as expected, although, since you're floating the inner divs left, they aren't in the dom float and lane-container appears to have a height of 0.

Parent div, height not set, over-sizes height by a few pixels to fit child img element height? Why?

In all major browsers: as the question states, a parent <div> container (whose height is not set) over-sizes its height to fit a child <img> element (for instance, a 300-pixel tall image that is the only thing inside the div). The over-sizing is usually about 3 to 5 pixels, and appears at first as img margin-bottom or div padding-bottom might look.
However, using absolute positioning, it is clearly demonstrated that the bottom of the div is below the bottom of the imgby a few pixels. It might not ruin a website's design, but it is a hurdle to overcome in certain situations. I have made a fairly detailed fiddle demonstrating this issue here.
Why is this standard practice in web browsers?
Is this meant to compensate for something? It seems unnecessary.
Is this a bug, or a soon-to-be antiquated feature?
EDIT: Thanks to the answerers/commentators below, I know the reason is that an <img> is treated by default as CSS
display:inline which preserves whitespace around the element.
Changing it to display:block completely fixes the problem by
eliminating whitespace around the element.
Notes: This over-sizing can be averted by giving the image child element a CSS property of float:left or float:right, etc., but this is a workaround, and as such is not the answer to the question. One reason this can be problematic is if you already have other float elements layered in front of the div child image (float overlap not allowed Firefox, Opera, IE. float overlapping only seems allowed in Chrome and Safari using CSS position settings). Thanks!
Add display:block to your image. I think that will fix the problem.

Why this behaviour (on ALL browsers) with margin-top?

This is my code :
HTML
<div class='father'>
<div class='son'>Son</div>
</div>
CSS
.father
{
background-color:blue;
}
.son
{
margin-top:50px;
background-color:red;
height:50px;
}
Where is the background-color blue of the father?
I know how to fix this problem (putting padding-top:1px to the father) but I'd like to know why of this behaviour!
For me it doesnt make sense, because on every browsers, not only IE, this is the behaviour.
This is a result of Collapsing Margins. You can read a good article by Eric Meyer on this topic where he illustrates this exact behavior. The following image is from his article.
Here's what the CSS2 specification has to say about it.
8.3.1 Collapsing margins
If the top and bottom margins of a box are adjoining, then it is
possible for margins to collapse through it. In this case, the
position of the element depends on its relationship with the other
elements whose margins are being collapsed.
If the element's margins are collapsed with its parent's top margin, the top border edge of the box is defined to be the same as
the parent's.
Otherwise, either the element's parent is not taking part in the margin collapsing, or only the parent's bottom margin is involved.
The position of the element's top border edge is the same as it
would have been if the element had a non-zero bottom border.
Note that the positions of elements that have been collapsed through
have no effect on the positions of the other elements with whose
margins they are being collapsed; the top border edge position is only
required for laying out descendants of these elements.
Source: http://www.w3.org/TR/CSS2/box.html#collapsing-margins
This is because the div is a block-level element. Certain block-level elements don't contain any padding by default. Divs are one such element. Block-level elements will take up the entire height and width of the container while respecting any padding it may contain.
W3C Visual formatting model
The parent element's height is set to its content's height by default. Once you set a height on the parent, that's no longer the default. Checking up on it, I believe that the padding adds to the height. So, the height is originally determined by the content unless otherwise stated in the CSS. Then, in most cases (IE 6 may be the exception), the padding is added to the height.
Good thing about SO, it helps us be much more detailed in our responses. :)
In CSS, block level elements naturally fills the elements content area, so your "son" div is filling your "father" div completely. Of course, you can bypass this by adding margin/padding/height to your parent div.
You're setting blue explicitly:
.father {
background-color:blue;
}
It's overridden (thanks to the "C" in CSS a.k.a cascading) but the style remains on your parent element (here, appropriately named "father").
If your .father box receives any height at all (check in the Firebug/Chrome dev tools inspector) than the blue is going to show through. I am guessing this is what you're seeing in IE (that or perhaps there's a flash of content before your child element style comes in). I don't think the IE debug tools show bounding boxes but you can test the element for it's height using JavaScript.
Moving outwards from the content, you have padding, border, and margin (as you probably know). Background covers only padding, but not margin.