Cheat Sheet: CSS Floats
Floats are a useful but tricky tool for altering what we call the “normal flow” of an HTML document. Remember the chief characteristics of normal flow: elements marked up with inline HTML tags (a
, strong
, em
, img
) march across the screen as if they were running text, falling to the next line only when they run out of horizontal sapce, whereas block level elements (p
, h1
, h2
, ul
, table
) start on a new line occupy their own horizontal space.
Float Basics
The simplest use case for a float is for an image at the beginning of a paragraph. This paragraph shows the default, unfloated behavior: because images are inline by default, the image takes up space as if it were very large text at the beginning of the paragraph, leaving a large space to the right and above them.
In this paragraph I’ve used the same markup, but this time I targeted the image with CSS and applied float:left;
as well as a small right margin: the image stays aligned to the left of the page but the paragraph now runs around it nicely.
Notice that this new paragraph also runs around the image. Note: this is the default behavior. Neither of the paragraphs (<p>
s) are themselves floated — just the image. Now for some dummy text to finish out the paragraph: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Finally, here’s the same image at the beginning of the paragraph again, but with float:right;
applied: the image goes as far as it can to the right until it hits the edge of the container, then allows content to flow around it. Now for some dummy text to finish out the paragraph: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Note: I tend to use right margins rather than left margins because I usually want the left edge of the first image (on each row) to align with its container.
Common task: Gallery
Floats come in handy when you want to create a grid of images. Use CSS to target all the images and float them all left, giving each a small right and bottom margin to separate them slightly:
Common task: Columns with Opposing Floats
Floats can be applied to all sorts of elements besides images: paragraphs, list items, and of course the all-purpose block-level container <div>
. When you have a design that requires column-like content areas, the technique known as “Opposing Floats” is often the most reliable. First, mark up your content however you wish and surround each content area with a div
. You’ll probably want to give your div
s classes or IDs (e.g. <div id="content">
and <div id="sidebar">
). Now in CSS, set a width on the columns you will be floating, then float one left and the other right.
This div has been styled with width:20%
and float:left;
This div has been styled with width:60%
and float:right;
. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
The nice part about this technique is that you don’t have to explicitly set a margin to separate the two columns: since the floats are in opposite directions, they naturally leave a space as long as their total width adds up to less than the width of their container. In addition, you don’t need to know in advance which column will end up being taller: the parent container will expand to contain them both.
Clearing Floats
Because of the default way that floats force content to wrap around them (refer to the paragraph above that begins with “notice that this new paragraph…” above), it’s common for a gallery like the one above to mess up the positioning of the heading or paragraph that follows it. Often it appears the content after the floats has been “sucked up” into the floated content.
To fix this problem, there are two possible solutions. The first is to apply clear:both;
to the element that you would like to force to begin on a new line. (You could also use clear:left;
or clear:right;
if you only want to clear one kind and not the other.) This works pretty reliably as long as you can easily target (with CSS) the content that follows the floats in the first place.
Clearfix
However, when content is being inserted dynamically or in different ways on different pages, it’s not always convenient to apply clear:both;
— the CSS “hook” just isn’t always available.
So some clever people figured out a way to use a CSS3 selector (:after
) to insert some dummy content, clear it, and then hide it from rendering on the page. It’s a hack known as clearfix
, and it enables you to clear floats by styling the container of the floats rather than the content that follows it.
The style might look like this in your CSS:
#gallery:after { /* use :after selector to insert content after the element */
content: "."; /* insert a period */
display: block; /* set it to be a block-level element */
height: 0; /* make sure it doesn't actually add space to the element */
clear: both; /* clear the inserted period */
visibility: hidden; /* make sure the period doesn't show up in the document */
}
Using classes
Because clearing floats is such a common task, you may end up filling your CSS file with dozens of statements that clear (or clearfix) this or that element. So many people choose to cheat a bit: in CSS we create classes with the names clear
and clearfix
and we insert these into our HTML wherever we need to clear some floats.
The CSS looks like this:
/* Float-clearing classes */
.clear {clear:both;}
.clearfix:after {content: "."; display: block; height: 0; clear: both; visibility: hidden;}
And in HTML:
[a bunch of stuff involving floats]
<h2 class="clear">The next section</h2>
or
<div class="clearfix">
[a bunch of stuff involving floats]
</div>
<h2>This heading should be fine</h2>
Remember, clear:both;
is for ensuring that something that comes after a bunch of floats doesn’t get pulled up into them. You apply it to the element that needs to be cleared. On the other hand, clearfix
is intended for the container of floated elements, and ensures the elements that come after that container don’t get pulled up into them.