Filling top-margin of a float

Hi,

I am trying to float a div to the right with a top-margin, inside another div whose contents wrap the right-float. Top-margin of the float is fixed (233px in the code below).

I kind of got it working in Firefox 3.x. The “main-content” div is pulled up by a negative top-margin, to fill the space left out by the bottom-margin of the “header” div, leaving the right-floated div underneath. But, it uses negative-margins. While, I was trying to find an answer in the sitepoint forums, I saw someone commenting “negative margins might turn ugly”. He/She was right.

Not surprisingly, chrome (webkit) refuses to fill the space provided after the negative margin and “main-content” wraps only as far as if there were no negative-margins.

I’m sorry the code below is a bit bloated; I needed those long paragraphs to make my point.

I know, I might be asking about the obvious; would absolute positioning be a help here? I would appreciate any tips and comments.

Thank you.

<!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>Filling Top-Margin of a Float</title>
<style type="text/css">
  body {
  margin: 0;
  padding: 0;
  }

  #main {
  width: 987px;
  margin: 0 auto;
  }

  #header {
  height: 144px;
  background: none repeat scroll 0 0 #CFC1A8;
  margin-bottom: 233px;
  color:  #808080;
  }

  #header h1 {
  margin: 11px 0 31px 264px;
  line-height: 42px;
  float: left;
  font-size: 2em;
  font-family: sans-serif;
  }

  #content {
  float: left;
  margin-left: 233px;
  width: 610px;
  line-height: 21px;
  text-align: justify;
  }

  #main-content {
  background: none repeat scroll 0 0 #FFF9EF;
  color: #6F6F6F;
  font-size: 15px;
  margin: -233px auto 0;
  padding: 15px 31px 21px;
  }

  #right-float {
  background: none repeat scroll 0 0 #CFCAC2;
  color: #5F5F5F;
  float: right;
  font-family: sans-serif;
  font-size: 13px;
  width: 181px;
  padding: 16px 31px 21px 21px;
  margin: 0 0 21px 21px;
  }
</style>
</head>

<body>
<div id="main">

<div id="header">
  <h1>Filling Top-Margin of a Float</h1>
</div> <!-- end of header -->

<div id="content">

<div id="right-float">
<p>Lorem ipsum dolor sit amet, tellus et. Molestie auctor nisl faucibus ut, lorem tortor mattis, fusce nullam enim fringilla vel. 
Mauris vitae gravida dolor praesent. Id in nascetur aut odio, nam et. Pede libero bibendum sit felis pretium sodales, fusce 
pharetra vestibulum bibendum morbi ultricies nullam, est nulla, id amet mollis. Nec consectetuer urna dapibus luctus ut, 
ipsum nascetur consequat dapibus dui ac molestie, est nascetur id nec nunc. Mi etiam mauris facilisi sed, nec ut id, 
aliquam non.</p>
</div>   <!-- end of right-float -->

<div id="main-content">
<p>Lorem ipsum dolor sit amet, tellus et. Molestie auctor nisl faucibus ut, lorem tortor mattis, fusce nullam enim fringilla vel. 
Mauris vitae gravida dolor praesent. Id in nascetur aut odio, nam et. Pede libero bibendum sit felis pretium sodales, fusce 
pharetra vestibulum bibendum morbi ultricies nullam, est nulla, id amet mollis. Nec consectetuer urna dapibus luctus ut, 
ipsum nascetur consequat dapibus dui ac molestie, est nascetur id nec nunc. Mi etiam mauris facilisi sed, nec ut id, 
aliquam non, taciti donec ut. Risus integer hymenaeos velit, nisl suspendisse sollicitudin ut, sed tempor sagittis curae dolor, 
volutpat massa ut sagittis. Voluptatem a enim, lobortis lectus volutpat, vitae vero diam purus morbi class, tristique donec 
ante sed, ac turpis dis dui vestibulum aut.
Tortor sit voluptatem pede sodales turpis hac, vel velit suscipit, luctus bibendum molestie lacinia neque. Porttitor ante 
turpis in voluptate vivamus autem, gravida magna amet porta praesent tincidunt at, nam enim sodales ante non, sit nunc 
posuere odio libero nibh ac. Amet id dignissim vehicula tempor et eros. Est hendrerit est quis, et viverra est class pede 
voluptas libero, sed mauris tincidunt, ultrices praesent. Iaculis vivamus sapien id, lorem ante aliquet, commodo pede imperdiet 
congue, dictum integer eget sed orci.</p>
<p>Lorem ipsum dolor sit amet, tellus et. Molestie auctor nisl faucibus ut, lorem tortor mattis, fusce nullam enim fringilla vel. 
Mauris vitae gravida dolor praesent. Id in nascetur aut odio, nam et. Pede libero bibendum sit felis pretium sodales, fusce 
pharetra vestibulum bibendum morbi ultricies nullam, est nulla, id amet mollis. Nec consectetuer urna dapibus luctus ut, 
ipsum nascetur consequat dapibus dui ac molestie, est nascetur id nec nunc. Mi etiam mauris facilisi sed, nec ut id, 
aliquam non, taciti donec ut. Risus integer hymenaeos velit, nisl suspendisse sollicitudin ut, sed tempor sagittis curae dolor, 
volutpat massa ut sagittis. Voluptatem a enim, lobortis lectus volutpat, vitae vero diam purus morbi class, tristique donec 
ante sed, ac turpis dis dui vestibulum aut.
Tortor sit voluptatem pede sodales turpis hac, vel velit suscipit, luctus bibendum molestie lacinia neque. Porttitor ante 
turpis in voluptate vivamus autem, gravida magna amet porta praesent tincidunt at, nam enim sodales ante non, sit nunc 
posuere odio libero nibh ac. Amet id dignissim vehicula tempor et eros. Est hendrerit est quis, et viverra est class pede 
voluptas libero, sed mauris tincidunt, ultrices praesent. Iaculis vivamus sapien id, lorem ante aliquet, commodo pede imperdiet 
congue, dictum integer eget sed orci.</p>
</div> <!-- end of main-content -->

</div>  <!-- end of content -->

</div> <!-- end of main -->
</body>
</html>

Thank you, Paul.

I didn’t quite understand it, until I changed the background-color of the “.spacer” div in firebug and added width to it; so that it’s wider than the padding-right of the “main-content” div, which is 31px.


div .spacer {
    width: 31px;
    background-color: grey;
}

That finally shrank the wrapping text in “main-content” to the left. The right-padding of the “main-content” div kind of ignores the float; it’s only when the width of the float hits the textual content (the wrapper), that the float affects the “main-content” div.

It took some time to grasp that. But, I get it now. :slight_smile:

Thanks again, guys.

Margins,padding and borders will slide under floats until they reach the containing block.

Floats are removed from the flow and content more or less behaves as if they aren’t there except that floats make room for themselves by repelling the foreground content out of the way.

Hi serdman. Welcome to SitePoint. :slight_smile:

There is a neat way to do this, but unfortunately I can’t remember it! Paul O’Brien (our resident guru) has a tutorial on it somewhere, but I couldn’t find it. Here is my (probably faulty) attempt to remember how it works:

<!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>Filling Top-Margin of a Float</title>
<style type="text/css">
  body {
  margin: 0;
  padding: 0;
  }
 
  #main {
  width: 987px;
  margin: 0 auto;
  }
 
  #header {
  height: 144px;
  background: none repeat scroll 0 0 #CFC1A8;
  color:  #808080;
  }
 
  #header h1 {
  margin: 11px 0 31px 264px;
  line-height: 42px;
  float: left;
  font-size: 2em;
  font-family: sans-serif;
  }
 
  #content {
  float: left;
  margin-left: 233px;
  width: 610px;
  line-height: 21px;
  text-align: justify;
  }
 
  #main-content {
  background: none repeat scroll 0 0 #FFF9EF;
  color: #6F6F6F;
  font-size: 15px;
  margin: 0 auto 0;
  padding: 15px 31px 21px;
  }
 
  #right-float {
  background: none repeat scroll 0 0 #CFCAC2;clear:right;
  color: #5F5F5F;
  float: right;
  font-family: sans-serif;
  font-size: 13px;
  width: 181px;
  padding: 16px 31px 21px 21px;
  margin: 10px 0 21px 21px;
  }

div.spacer {width: 1px; height: 233px;float: right;border-right: 1px solid #FFF9EF;}
</style>
</head>
 
<body>
<div id="main">
 
<div id="header">
  <h1>Filling Top-Margin of a Float</h1>
</div> <!-- end of header -->
 
<div id="content">
<div class="spacer">
</div>
<div id="right-float">

<p>Lorem ipsum dolor sit amet, tellus et. Molestie auctor nisl faucibus ut, lorem tortor mattis, fusce nullam enim fringilla vel.
Mauris vitae gravida dolor praesent. Id in nascetur aut odio, nam et. Pede libero bibendum sit felis pretium sodales, fusce
pharetra vestibulum bibendum morbi ultricies nullam, est nulla, id amet mollis. Nec consectetuer urna dapibus luctus ut,
ipsum nascetur consequat dapibus dui ac molestie, est nascetur id nec nunc. Mi etiam mauris facilisi sed, nec ut id,
aliquam non.</p>
</div>   <!-- end of right-float -->
 
<div id="main-content">
<p>Lorem ipsum dolor sit amet, tellus et. Molestie auctor nisl faucibus ut, lorem tortor mattis, fusce nullam enim fringilla vel.
Mauris vitae gravida dolor praesent. Id in nascetur aut odio, nam et. Pede libero bibendum sit felis pretium sodales, fusce
pharetra vestibulum bibendum morbi ultricies nullam, est nulla, id amet mollis. Nec consectetuer urna dapibus luctus ut,
ipsum nascetur consequat dapibus dui ac molestie, est nascetur id nec nunc. Mi etiam mauris facilisi sed, nec ut id,
aliquam non, taciti donec ut. Risus integer hymenaeos velit, nisl suspendisse sollicitudin ut, sed tempor sagittis curae dolor,
volutpat massa ut sagittis. Voluptatem a enim, lobortis lectus volutpat, vitae vero diam purus morbi class, tristique donec
ante sed, ac turpis dis dui vestibulum aut.
Tortor sit voluptatem pede sodales turpis hac, vel velit suscipit, luctus bibendum molestie lacinia neque. Porttitor ante
turpis in voluptate vivamus autem, gravida magna amet porta praesent tincidunt at, nam enim sodales ante non, sit nunc
posuere odio libero nibh ac. Amet id dignissim vehicula tempor et eros. Est hendrerit est quis, et viverra est class pede
voluptas libero, sed mauris tincidunt, ultrices praesent. Iaculis vivamus sapien id, lorem ante aliquet, commodo pede imperdiet
congue, dictum integer eget sed orci.</p>
<p>Lorem ipsum dolor sit amet, tellus et. Molestie auctor nisl faucibus ut, lorem tortor mattis, fusce nullam enim fringilla vel.
Mauris vitae gravida dolor praesent. Id in nascetur aut odio, nam et. Pede libero bibendum sit felis pretium sodales, fusce
pharetra vestibulum bibendum morbi ultricies nullam, est nulla, id amet mollis. Nec consectetuer urna dapibus luctus ut,
ipsum nascetur consequat dapibus dui ac molestie, est nascetur id nec nunc. Mi etiam mauris facilisi sed, nec ut id,
aliquam non, taciti donec ut. Risus integer hymenaeos velit, nisl suspendisse sollicitudin ut, sed tempor sagittis curae dolor,
volutpat massa ut sagittis. Voluptatem a enim, lobortis lectus volutpat, vitae vero diam purus morbi class, tristique donec
ante sed, ac turpis dis dui vestibulum aut.
Tortor sit voluptatem pede sodales turpis hac, vel velit suscipit, luctus bibendum molestie lacinia neque. Porttitor ante
turpis in voluptate vivamus autem, gravida magna amet porta praesent tincidunt at, nam enim sodales ante non, sit nunc
posuere odio libero nibh ac. Amet id dignissim vehicula tempor et eros. Est hendrerit est quis, et viverra est class pede
voluptas libero, sed mauris tincidunt, ultrices praesent. Iaculis vivamus sapien id, lorem ante aliquet, commodo pede imperdiet
congue, dictum integer eget sed orci.</p>
</div> <!-- end of main-content -->
 
</div>  <!-- end of content -->
 
</div> <!-- end of main -->
</body>
</html>

You could PM him to ask for a better solution (if he doesn’t find this thread anyway :slight_smile: ).

Ralphs method is the safest to use and is called a “sandbag” . Ray has a demo here showing it in action.

If you only want IE8+ support then you can do away with the extra element and just add the sandbag with the css content property.


#content:before {
  content:" ";
	width: 1px;
	overflow:hidden;
	height: 233px;
	float: right;
	border-right: 1px solid #FFF9EF;
}


Thanks for the quick reply ralph.m. This works!

All I needed was another (widthless?) float right, the “main-content” div could wrap to.

What I don’t understand is why it works, what happens to to the width (1 + 1 = 2px) of the “.spacer” div. How come I dont see the border hanging on the right, and (at least on firebug and chrome-developer-tools) width + padding of the “main-content” still looks to be 610px, as it should be.

But the “.spacer” is sure there, too. When I give border and background of the “.spacer” div a different color each, I can see them both, nicely vertically aligned with “right-float” on the right; so the width is there, right? How come “610 + 2” is equal to “610”?

I would appreciate any comment or a pointer.

Thank you.

That’s a nice demo, Paul. Thank you.

The float needs to have at least 1px width for IE6 and 7 but all other browsers are happy with the width being zero.

How come I dont see the border hanging on the right,

Change the border-color to red and you will see it. The border isn’t really needed though.


div.spacer {
	width:1px;
	height: 233px;
	float: right;
	overflow:hidden;
}

What I don’t understand is why it works,

It’s just a right float like any other normal float and the text will wrap as normal. The following real float is set to clear:right so it starts underneath this tall sandbag float. Floats need to be continuous if you want text to wrap all the way to the top.

With this method you could have multiple sandbag floats that are different widths and only a line-height high and then you can create shapes like a curve that text will wrap around.

what happens to to the width (1 + 1 = 2px) of the “.spacer” div. How come I dont see the border hanging on the right, and (at least on firebug and chrome-developer-tools) width + padding of the “main-content” still looks to be 610px, as it should be.

But the “.spacer” is sure there, too. When I give border and background of the “.spacer” div a different color each, I can see them both, nicely vertically aligned with “right-float” on the right; so the width is there, right? How come “610 + 2” is equal to “610”?

Nothing is happening to the width and the float is inside the 610px div so I don’t know why you are adding it to the float. The two elements have nothing in common.:slight_smile: It’s just another float inside a container just like normal - nothing special except that its very narrow.

You’ll need to add display:inline for IE6 as you have the double margin bug here:


#content {
	float: left;
	margin-left: 233px;
	width: 610px;
	line-height: 21px;
	text-align: justify;
	[B]display:inline;[/B]
}