~ a negative margin oddity ~

Hi there gurus,

whilst helping a member in another forum to be aware of the natural stacking
order of elements with the implementation of negative margins I discovered,
what appears to me to be, an oddity. :confused:

If you take a look at this example…

[color=navy]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<base href="http://www.coothead.co.uk/images/">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="language" content="english"> 
<meta http-equiv="Content-Style-Type" content="text/css">

<title>natural stacking order</title>

<style type="text/css">
body {
    background-color:#ccc;
 }
#apple {
    display:block;
    width:360px;
    height:280px;
    border:5px double #000;
 }
#banana {
    display:block;
    width:360px;
    height:280px;
    border:5px double #000;
    margin-top:-145px;
    margin-left:185px;
 }
#ball {
    display:block;
    width:300px;
    height:300px;
    border:5px double #000;
    margin-top:-145px;
    margin-left:365px;
 }
</style>

</head>
<body>

<div>
 <img id="apple" src="apple.jpg" alt="apple">
 <img id="banana" src="banana.jpg" alt="banana">
 <img id="ball" src="ball_shad.jpg" alt="ball">
</div>

</body>
</html>
[/color]

…you will see that that the image stacking order is as expected but the border
attribute has a reversed stacking order?

Can anyone provide enlightenment. :wink:

coothead

Thank you very much, everyone, for your inputs. :wink:

Hi there WHHG,

thanks for your input. :wink:

I am, of course, aware that using the float attribute will achieve the “correct result”.
Funnily enough, IE6 keeps the border above. :lol:
Adding position:relative to the images also achieves the “correct result”.

A logical explanation for the behaviour of the code that I have used though is still required.

As a matter of interest it does work as expected with a block element…

[color=navy]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="language" content="english"> 
<meta http-equiv="Content-Style-Type" content="text/css">

<title></title>

<style type="text/css">
#top {
    width:360px;
    height:280px;
    border:5px double #000;
    background-color:#505050;
 }
#middle {
    width:360px;
    height:280px;
    border:5px double #000;
    margin-top:-145px;
    margin-left:185px; 
    background-color:#f00;
 }
#bottom {
    width:300px;
    height:300px;
    border:5px double #000;
    margin-top:-145px;
    margin-left:365px;
    background-color:#fff;
 }
</style>

</head>
<body>

<div id="top"></div>
<div id="middle"></div>
<div id="bottom"></div>

</body>
</html>
[/color]

coothead

I think it might be the display:block; parameter being given to the <img> tag. If you use this css instead it works correctly:

<style type="text/css">
body {
    background-color:#ccc;
 }
#apple {
    float: left;
    width:360px;
    height:280px;
    border:5px double #000;
 }
#banana {
    float: left;
    width:360px;
    height:280px;
    border:5px double #000;
    margin-top:100px;
    margin-left:-100px;
 }
#ball {
    float: left;
    width:300px;
    height:300px;
    border:5px double #000;
    margin-top:200px;
    margin-left:-100px;
 }
</style>

It just has to do with the <img> element and the fact it is a replaced inline element (probably).

I don’t have an explanation that really makes sense in my head. I just think it’s the tags that are the issue. Display:block makes elements almost exactly like other block elements (aka <div>) so this is just probably the element itself that is the problem :slight_smile:

Yeah, I would agree with you Ryan.

Even though the images were given block displays the <img> tag along with doctype rendering excludes the image from normal block stacking behavior.

Inline elements in their natural environment can’t take on vertical margins so I would assume that is playing a role in the way the borders are behaving.

You will find an explanation of the stacking level order in the Stacking Context Description (implemented in good browsers).

Starting with the canvas as the lowest, text and inline replacements comes high in the stacking order; at 7.2.1.4.1 and apart from outlines only positioned element’s auto level becomes higher. Block’s stacking level comes at 4 and their borders comes at 4.3 layered in the block’s source order.

So your block displayed images gets their borders atttaced to the block box, but the image tag’s content is displayed as the replaced inline content it is. (Note that if the image is missing the alt-text is the inline content.)

Stacking order test example; block boxes vs text and inline box:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<meta name="generator" content="PSPad editor, www.pspad.com">
<style type="text/css">
div{
	float:left;
	padding:3em;
	background:#ccc;
	font-size:3em;
}
#a{
	display:block;
	margin-top:-1em;
	border:5px double #c00;
	background:#f99;
	color:#c00;
}
#b{
	display:block;
	margin:-2em -2em 0 2em;
	border:5px double #0c0;
	background:#9f9;
	color:#0c0;
}
#b span{
	border:5px double #6f6;
	background:#cfc;
	color:#6f6;
}
#c{
	display:block;
	margin:-2em -1em 0 1em;
	border:5px double #00c;
	background:#99f;
	color:#00c;
}
#c span{
	display:block;
	border:5px double #66f;
	background:#ccf;
	color:#66f;
}
</style>
</head><body>

<div>
 <span id="a">1 Inline content in<br>a block element</span>
 <span id="b">2 Inline content<br><span>Inline element</span></span>
 <span id="c">3 Inline content<span>Block element</span></span>
</div>

</body></html>

Erik has explained the reasons precisely above :slight_smile:

As I always point out that when you use negative margins and expect overlap/underlap then simply add position:relative also. (IE will quite often drag block content under the background also so it’s a win win method :slight_smile: )