Page Layout With Floats and Positioning: Learning Web Design, 5e
Page Layout With Floats and Positioning: Learning Web Design, 5e
POSITIONING
CSS Grid and Flexbox (see Note) were designed from the ground up to give IN THIS ARTICLE
designers control over page layout, and now that those standards have solid
Two- and three-column layouts
browser support, they are definitely the way to go moving forward. However,
using floats
we are still in a time of transition. Older, non-supporting browsers (Internet
Explorer in particular) have a way of stubbornly hanging around, and as long A source-independent layout
as they continue to show up in significant numbers in our visitor statistics, using floats
we need to provide reasonable fallbacks for our Grid- and Flexbox-based
designs. That’s where knowing the old float- and position-based layout tech- A three-column layout using
absolute positioning
niques may still come in handy.
I’ve made this article (originally a chapter from the fourth edition of Learning Top-to-bottom “faux” column
Web Design) available should you need to support old browsers that support backgrounds
neither Grid nor Flexbox. Otherwise, these techniques should be considered
obsolete and should be avoided in favor of proper layout standards.
This article contains templates and techniques for the following:
• Two- and three-column layouts using floats
N OT E
• A source-independent layout using floats and negative margins
I cover Grid and Flexbox in detail in
• A multicolumn layout using positioning
Chapter 16, CSS Layout with Flexbox
To get the most out of the examples, you will need a solid understanding of and Grid, of Learning Web Design, 5e
how floating and positioning work, as presented in Chapter 15, Floating and (O’Reilly).
Positioning, in Learning Web Design, 5e.
The examples in this article are intended to be a “starter kit.” They should
give you a good head start toward understanding how layout works, but they
are not universal solutions. The templates presented here are simplified and
may not work for every situation, although I’ve tried to point out the relevant
shortcomings of each. Your content may dictate more complicated solutions.
1
Multiple Columns Using Floats
Float one column element to the right or left and add a margin on the
remaining column element. Clear the footer element to keep it at the bot-
tom of the page. The underlying structure and resulting layout is shown in
FIGURE A.
header
main
aside
footer
THE MARKUP
THE STYLES
main {
float: left;
width: 60%;
margin: 0 5%;
}
aside {
width: 25%;
margin-left: 70%;
}
footer {
clear: left;
}
NOTES
This one is pretty straightforward, but because this is our first one, I’ll point
a few things out:
• Remember that I’ve omitted the styles for the header, footer, and text to
keep the examples as simple as possible. Keep in mind that there is a bit
more at work in here than what is listed under “The styles” (nothing
you couldn’t figure out, though: background colors, padding, stuff like
that). There are also 3px dashed outlines applied to the main and aside
elements to make the structure clearer in the figure. This is true for all
examples in this article.
• The source document has been divided into elements: header, main,
aside, and footer. The markup shows the order in which they appear in
the source.
• The main element has been floated to the left and given a width of 60%
with 5% margins on the left and right sides.
• The aside element has been wrapped around the main element. It has a
left margin of 70%, enough to make room for the main element box (60%
box width plus 10% margin width).
• The footer is cleared so it starts below the floated content.
Set widths on both column elements and float them to the left. Clear the
footer to keep it at the bottom of the page. The underlying structure and
resulting layout is shown in FIGURE B.
header
main
aside
footer
<header>Masthead and headline</header> This one has the same visual result as the first two-column
<main>Main article</main> example, which goes to show you that there are often mul-
<aside>List of links and news</aside> tiple approaches to a single design goal. In this approach:
<footer>Copyright information</footer> • Both main and aside have been floated to the left.
Because they are floats, widths were specified for each.
THE STYLES
You can make your columns as wide as you like.
main {
float: left; • The main element has a 5% margin applied on the left
width: 60%; and right sides. The aside element needs a margin only
margin: 0 5%; on the right. The margins on the top have been set to 0
}
aside { so they vertically align.
float: left;
• The footer is cleared so it starts below the floated content.
width: 25%;
margin: 0 5% 0 0;
}
footer {
clear: left; TIP
}
You could also float one column to the left and the other to the
right for the same effect.
#wrapper {
width: 960px;
}
main {
float: left;
width: 650px;
margin: 0 20px;
}
aside {
float: left;
width: 250px;
margin: 0 20px 0 0;
}
footer {
clear: left;
}
NOTES
• All of the content is contained in a div (#wrapper) that has been set to
960 pixels wide.
#wrapper
header
main
aside
footer
• I’ve changed the widths and margins to pixel measurements as well, tak-
ing care not to exceed a total of 960. If they added up to more than the
width of the #wrapper container, we’d get the dreaded float drop. Keep in
mind that if you add padding or borders, the total of their widths would
need to be subtracted from the width values to keep the total width the
same unless you use the border-box box-sizing model.
THE STRATEGY
Set the left and right margins on the #wrapper container to auto, which keeps
the whole page centered. The markup is exactly the same as in the previous
example. We only need to add a margin declaration to the styles. Easy as pie.
The resulting layout is shown in FIGURE D.
THE STYLES
#wrapper {
width: 960px;
margin: 0 auto;
}
NOTES
• The auto margin setting on the left and right sides keeps the #wrapper
centered in the browser window.
#wrapper
header
main
extras
footer
THE STRATEGY
Set widths on all three-column elements and float them to the left. Clear
the footer to keep it at the bottom of the page. The underlying structure and
resulting layout is shown in FIGURE F.
header
#links
main
#news
footer
TIP
L AYO U T T I P
You can avoid this whole ordering conundrum by using Flexbox or Grid for columns
instead of hacking floats, as this “holy grail” approach clearly does. You can change
the display order of flex items and to place grid items in any cell area you choose.
THE STRATEGY
Apply widths and floats to all three column elements, and use a negative
margin to “drag” the third column across the page into the left position. The
underlying structure and resulting layout is shown in FIGURE H. Notice that
although main comes first in the source, it is in the second-column position.
In addition, the #links div (last in the source) is in the first-column position
on the left. This example is fixed, but you can do the same thing with a fluid
layout by using percentage values.
#wrapper
header
main
#news
#links
footer
FIGURE H. A fixed-width, three-column layout using three floats. It looks like the
previous example, but it is special in that the column order is not the same as the
source order.
NOTES
This one requires a bit more explanation, so we’ll look at how it’s done one
step at a time.
In the markup, we see that main comes first, presumably because it is the
most important content, and #links comes last. The whole page is wrapped
in a div (#wrapper) so that it can be set to a specific width (960px). In the
layout, however, the order of the columns from left to right is #links (200px
wide), main (520px wide), then #news (200px wide). This layout has 20 pixels
of space between columns.
The first step to getting there is moving the main section to the middle posi-
tion by applying a left margin that pushes it over enough to make room for
the left column (200px) plus the space between (20px); so, margin-left:
220px. While we’re at it, we’ll add a 20px right margin on main as well to
make room on its right side. FIGURE I shows how the page looks after we
apply styles to main.
Next—and this is the cool part—pull the content that you want to go in the
left column (#links, in this case) to the left by using a negative margin value.
The trick is figuring out how far to the left it needs to be moved. If you look
at FIGURE I, you can see a ghostly version of #links that shows where it wants
to be if the #wrapper were wide enough. I find it useful to look at the layout
in that way because it makes it clear that we need to pull #links to the left by
the widths of all the element boxes ahead of it in the source.
FIGURE I. The layout after margins are applied to the middle (main) column element.
The shaded box on the right shows where #links would like to be if it weren’t forced
under #news.
In this example, the element box width for main is 520px + 220px for the left
margin + 20px for the right margin, for a total of 760 pixels. The total width
of #news is 200px (no margins are applied). That means that the #links div
needs to be pulled a total of 960 pixels to the left to land in the left-column
slot (margin-left: -960px;). When the negative margin is applied, #links WA R N I N G
slides into place, and we have the final layout shown in FIGURE H.
When you are doing this on your own,
If we wanted the #news div to be in the left column (FIGURE J), we’d take the remember to include padding and bor-
same approach: float all the elements to the left, give the #main element a ders into the total element box width
wide left margin (220px), and then use a negative margin to pull #news to the calculations as well, unless you are using
left. The left margin on #news needs to be -760px (220 + 520 + 20) to move it the border-box box-sizing model.
across the width of the #main element and its two side margins.
FIGURE J. Floating the News div to the left column with a margin of –760px.
POSITIONED LAYOUT
I think we’ve got floated columns covered. The other way to create columns
in a layout is to use absolute positioning. In this section, we’ll use positioning
to arrange three columns in both fluid and fixed-width pages.
Note that in both examples, I have omitted the footer element. I’ve done
this for a couple of reasons. First, when you position all of the elements in a
layout, as we will in these examples, they no longer “participate in the layout,”
which means there is nothing to hold a footer at the bottom of the page. It
rises right up to the top. There are solutions to this problem using JavaScript,
but they are beyond the scope of this article.
But say we position only the two side columns and let the main center col-
umn stay in the flow to hold the footer down. This is certainly a possibility,
but if either of the side columns grows longer than the center column, it will
overlap the footer content. Between leaping footers and potential overlaps, it’s
just kind of messy, which is why I’ve chosen to omit the footer here (and why
floats are the more popular layout technique).
header
#content
main
#links
#news
THE STRATEGY
Wrap the three sections (main, #news, #links) in a div (#content) to serve as
a containing block for the three positioned columns. Then give the column
elements widths and position them in the containing #content element.
THE MARKUP
THE STYLES
#content {
position: relative;
margin: 0;
}
main {
width: 50%;
position: absolute;
top: 0;
left: 25%;
margin: 0;
}
#news {
width: 20%;
position: absolute;
top: 0;
left: 2.5%;
margin: 0;
}
#links {
width: 20%;
position: absolute;
top: 0;
right: 2.5%;
margin: 0;
}
NOTES
I think that you’ll find the styles for this layout to be fairly straightforward.
• I created the #content containing block to position the columns because
we want the columns to always start below the header. If we positioned
them relative to the browser window (the initial containing block), they
may be in the wrong spot if the height of the header should change, such
as the result of the h1 text changing size. Make the #content div a contain-
ing block by applying the declaration position: relative.
• The main element is given a width of 50%, and absolute positioning is
used to place it at the top of the #content div and 25% from the left edge.
This will accommodate the 20% width of the left column plus the 2.5%
space that serves as a margin to the left and right of it.
• The #news div is positioned at the top of the #content div and 2.5% from
the left edge (top: 0; left: 2.5%;).
• The #links div is positioned at the top of the #content div and 2.5% from
the right edge (top: 0; right: 2.5%;). No need to calculate the position
from the left edge…just put it on the right! Note that we could have posi-
tioned the #news and #links columns flush against their respective edges
and used padding to make a little space on the sides. There are usually
multiple ways to approach layout goals.
• The only trick to getting this right is making sure your width and margin
measurements do not exceed 100%. You may need to factor in padding
and borders as well.
#wrapper
header
#content
main
#links
#news
THE STYLES
#wrapper { #news {
width: 960px; width: 200px;
margin: 0 auto; position: absolute;
} top: 0;
#content { left: 0;
margin: 0; margin: 0;
position: relative; }
} #links {
main { width: 200px;
width: 520px; position: absolute;
position: absolute; top: 0;
top: 0; right: 0;
left: 220px; margin: 0;
margin: 0; }
}
TOP-TO-BOTTOM COLUMN
BACKGROUNDS
Adding color to columns is an effective way to emphasize the division of
information and bring a little color to the page. But if you look at the dashed
borders in all the screenshot examples we’ve seen so far, you’ll see that col-
umn elements often stop well before the bottom of the page. This is one dis-
N OT E
advantage of using floats and positioning for columns. If you want to apply
backgrounds from top to bottom in columns, you need to get tricky and use The problem of uneven columns is solved
tiling background images in a technique known as “faux columns.” in CSS Grid and Flexbox, where you can
stretch items to fill the available height.
TIP
background-position: 67.5%
two_cols_5000px.png
FIGURE N. The background image is anchored at the point between the two
columns, so when the browser window gets larger or smaller, it is always in the right
place. The graphic file is wide enough that there will be enough image to fill both
columns, even on the widest of browsers.
18 Learning Web Design, 5e
Top-to-Bottom Column Backgrounds