2015 update: the flexbox approach
There are two other answers briefly mentioning flexbox; however, that was more than two years ago, and they don't provide any examples. The specification for flexbox has definitely settled now.
Note: Though CSS Flexible Boxes Layout specification is at the Candidate Recommendation stage, not all browsers have implemented it. WebKit implementation must be prefixed with -webkit-; Internet Explorer implements an old version of the spec, prefixed with -ms-; Opera 12.10 implements the latest version of the spec, unprefixed. See the compatibility table on each property for an up-to-date compatibility status.
(taken from https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes)
All major browsers and IE11+ support Flexbox. For IE 10 or older, you can use the FlexieJS shim.
To check current support you can also see here:
http://caniuse.com/#feat=flexbox
Working example
With flexbox you can easily switch between any of your rows or columns either having fixed dimensions, content-sized dimensions or remaining-space dimensions. In my example I have set the header to snap to its content (as per the OPs question), I've added a footer to show how to add a fixed-height region and then set the content area to fill up the remaining space.
html,
body {
height: 100%;
margin: 0;
}
.box {
display: flex;
flex-flow: column;
height: 100%;
}
.box .row {
border: 1px dotted grey;
}
.box .row.header {
flex: 0 1 auto;
/* The above is shorthand for:
flex-grow: 0,
flex-shrink: 1,
flex-basis: auto
*/
}
.box .row.content {
flex: 1 1 auto;
}
.box .row.footer {
flex: 0 1 40px;
}
<!-- Obviously, you could use HTML5 tags like `header`, `footer` and `section` -->
<div class="box">
<div class="row header">
<p><b>header</b>
<br />
<br />(sized to content)</p>
</div>
<div class="row content">
<p>
<b>content</b>
(fills remaining space)
</p>
</div>
<div class="row footer">
<p><b>footer</b> (fixed height)</p>
</div>
</div>
In the CSS above, the flex property shorthands the flex-grow, flex-shrink, and flex-basis properties to establish the flexibility of the flex items. Mozilla has a good introduction to the flexible boxes model.
Depending upon the design being produced, each of the below clearfix CSS solutions has its own benefits.
The clearfix does have useful applications but it has also been used as a hack. Before you use a clearfix perhaps these modern css solutions can be useful:
Modern Clearfix Solutions
Container with overflow: auto;
The simplest way to clear floated elements is using the style overflow: auto
on the containing element. This solution works in every modern browsers.
<div style="overflow: auto;">
<img
style="float: right;"
src="path/to/floated-element.png"
width="500"
height="500"
>
<p>Your content here…</p>
</div>
One downside, using certain combinations of margin and padding on the external element can cause scrollbars to appear but this can be solved by placing the margin and padding on another parent containing element.
Using ‘overflow: hidden’ is also a clearfix solution, but will not have scrollbars, however using hidden
will crop any content positioned outside of the containing element.
Note: The floated element is an img
tag in this example, but could be any html element.
Clearfix Reloaded
Thierry Koblentz on CSSMojo wrote: The very latest clearfix reloaded. He noted that by dropping support for oldIE, the solution can be simplified to one css statement. Additionally, using display: block
(instead of display: table
) allows margins to collapse properly when elements with clearfix are siblings.
.container::after {
content: "";
display: block;
clear: both;
}
This is the most modern version of the clearfix.
⋮
⋮
Older Clearfix Solutions
The below solutions are not necessary for modern browsers, but may be useful for targeting older browsers.
Note that these solutions rely upon browser bugs and therefore should be used only if none of the above solutions work for you.
They are listed roughly in chronological order.
"Beat That ClearFix", a clearfix for modern browsers
Thierry Koblentz' of CSS Mojo has pointed out that when targeting modern browsers, we can now drop the zoom
and ::before
property/values and simply use:
.container::after {
content: "";
display: table;
clear: both;
}
This solution does not support for IE 6/7 …on purpose!
Thierry also offers: "A word of caution: if you start a new project from scratch, go for it, but don’t swap this technique with the one you have now, because even though you do not support oldIE, your existing rules prevent collapsing margins."
Micro Clearfix
The most recent and globally adopted clearfix solution, the Micro Clearfix by Nicolas Gallagher.
Known support: Firefox 3.5+, Safari 4+, Chrome, Opera 9+, IE 6+
.container::before, .container::after {
content: "";
display: table;
}
.container::after {
clear: both;
}
.container {
zoom: 1;
}
Overflow Property
This basic method is preferred for the usual case, when positioned content will not show outside the bounds of the container.
http://www.quirksmode.org/css/clearing.html
- explains how to resolve common issues related to this technique, namely, setting width: 100%
on the container.
.container {
overflow: hidden;
display: inline-block;
display: block;
}
Rather than using the display
property to set "hasLayout" for IE, other properties can be used for triggering "hasLayout" for an element.
.container {
overflow: hidden;
zoom: 1;
display: block;
}
Another way to clear floats using the overflow
property is to use the underscore hack. IE will apply the values prefixed with the underscore, other browsers will not. The zoom
property triggers hasLayout in IE:
.container {
overflow: hidden;
_overflow: visible; /* for IE */
_zoom: 1; /* for IE */
}
While this works... it is not ideal to use hacks.
PIE: Easy Clearing Method
This older "Easy Clearing" method has the advantage of allowing positioned elements to hang outside the bounds of the container, at the expense of more tricky CSS.
This solution is quite old, but you can learn all about Easy Clearing on Position Is Everything: http://www.positioniseverything.net/easyclearing.html
Element using "clear" property
The quick and dirty solution (with some drawbacks) for when you’re quickly slapping something together:
<br style="clear: both" /> <!-- So dirty! -->
Drawbacks
- It's not responsive and thus may not provide the desired effect if layout styles change based upon media queries. A solution in pure CSS is more ideal.
- It adds html markup without necessarily adding any semantic value.
- It requires a inline definition and solution for each instance rather than a class reference to a single solution of a “clearfix” in the css and class references to it in the html.
- It makes code difficult to work with for others as they may have to write more hacks to work around it.
- In the future when you need/want to use another clearfix solution, you won't have to go back and remove every
<br style="clear: both" />
tag littered around the markup.
Best Answer
First, make sure you are using a doctype that will put IE7 into strict mode (see http://hsivonen.iki.fi/doctype/ for an explaination). if that doesn't do it, it may be that you need some play in your margin widths.
The reason why you have to have the sidebar div first, is since div is a displayed as a block element anything after it, will be below it (unless you float the main div).
By floating the sidebar div and putting it first, the browser knows it can display the main div to the right of the sidebar. You could get a similar effect by adding float left to the main div and removing the float from the sidebar div and moving it after the main div.