Automatically adjust the height of a CSS box to accommodate floated content
Content |
Objective
Background
When the height of a CSS box adjusts to fit its content, the area occupied by any floated elements is normally disregarded. This is an intended feature of the stylesheet language, needed to allow layouts such as the one below in which a floated image overlaps two paragraphs:

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
The behaviour is rather less helpful when there is not enough running text for the image to flow into. The page is then laid out in a manner that accommodates the running text, but not the floating element. This can cause the floating element to overlap with components of the page that ought to lie beneath it, such as the outer border in the scenario described below.
Scenario
Suppose that you wish to display a box containing text and an image, as in the example above, but with only one paragraph of text:

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Note how the image overlaps the outer border. Here is the relevant section of the page markup:
<div style="border: black solid thin;"> <img src="image1.png" style="float: right;"> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> </div>
You want to prevent any overlap between the outer border and the content of the box. Specifically, you want the height of the outer box to change automatically so that it is tall enough to accommodate the text and the image, but no taller.
Methods
Tested on |
Chrome (9, 10, 11, 12, 13) |
Firefox (1.0, 1.5, 2.0, 3.0, 3.5, 3.6, 4, 5, 7, 11) |
IE (6, 7, 8, 9) |
Opera (8, 9, 10, 11) |
Safari (4, 5) |
clear: both
One way to achieve the desired effect is to place an empty block-level element beneath the text and floating image, but within the outer box. The clear
property of this element should be set to both
:
<div style="border: black solid thin;"> <img src="image1.png" style="float: right;"> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> <div style="clear: both;"></div> </div>
Because the empty box is not itself a floating element, it is taken into account when calculating the required height of the outer box. Its position in the markup ensures that it is placed below the text, and the value of its clear
property ensures that it is placed below any floating content.

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
This method should work in any browser that supports CSS. Its main drawback is the need for an extra div
element that serves no semantic purpose. This is considered undesirable because it mixes presentation with content.
Tested on |
Chrome (9, 10, 11, 12, 13) |
Firefox (1.0, 1.5, 2.0, 3.0, 3.5, 3.6, 4, 5, 7, 11) |
IE (7, 8, 9) |
Opera (8, 9, 10, 11) |
Safari (4, 5) |
Fails on |
IE (6) |
Setting overflow to hidden
An alternative method is make use of the overflow
property of the outer box. Setting this to any value other than
visible
causes the height of any floating elements to be taken into account when calculating the required height. A value of hidden
minimises the risk of unwanted scrollbars appearing:
<div style="border: black solid thin; overflow: hidden;"> <img src="image1.png" style="float: right;"> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> </div>
The effect should be similar to that of clear: both
, but without the need for an empty div
element that exists only for the purpose of formatting. However this method should not be used if the outer box has any relatively-positioned content that is intended to project outside its border, because such content would be truncated.
This method should work in any browser that supports CSS 2.1 or better. (The overflow
property was introduced in CSS2, but it was not until CSS2.1 that it had the behaviour described here: previously it was required to do the opposite.) It is known to fail in Internet Explorer 6. If that is a concern then it can be combined with the hasLayout
hack described here and here.
Tested on |
Chrome (9, 10, 11, 12, 13) |
Firefox (1.0, 1.5, 2.0, 3.0, 3.5, 3.6, 4, 5, 7, 11) |
Internet Explorer (8, 9) |
Opera (8, 9, 10, 11) |
Safari (4, 5) |
Fails on |
IE (6, 7) |
Using the :after pseudo-class
The :after
pseudo-class allows extra content to be inserted into the document tree as it is rendered. This makes it possible to implement the clear:both
method without there being any extra markup in the source document:
<style type="text/css"> .clearfix:after { content: ""; display: block; clear: both; } </style> <div class="clearfix" style="border: black solid thin;"> <img src="image1.png" style="float: right;"> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> </div>
This method should work in any browser that supports CSS 2 or better. It is known to fail in Internet Explorer 6 and 7, which do not support the :after
pseudo-class. If this is a concern then it can be combined with the hasLayout
hack noted above.
Further reading
- Cascading Style Sheets, level 1, W3C, December 1996
- Cascading Style Sheets, level 2, W3C, May 1998
- Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification, W3C, June 2011
- Tony Aslett, Contained Floats, enclosing floats with pure CSS known as the clearfix technique, CSS Creator, May 2004
- How To Clear Floats Without Structural Markup, Position Is Everything, May 2004
- Alex Walker, Simple Clearing of Floats, SitePoint, February 2005
Tags: css