This article originally appeared on

Back in the early days of the Internet boom, I wrote some pretty ugly code to get pages to look and act the way I thought they should. I spent hours preparing the countless graphics files needed to create mouseover effects and menu bars, only to find that they took too long to load over a 28.8 modem. I longed for the day when bandwidth would flow like water so that my pages would load quickly.

Ironically, now that bandwidth is more plentiful, graphics-heavy code has gone out of style. Fortunately, Cascading Style Sheets 2 (CSS2) allows us to use its border attribute to re-create effects with code that used to require graphics.

Page layout
I used to spend a lot of time tinkering with TABLE tags, spacer GIFs, and background colors to make my page layout look just right. Unfortunately, the resulting code was often unnecessarily bloated. It was also difficult and time-consuming to change the layout once it was coded.

With CSS2, especially its border attribute, an entire page can be laid out without a single TABLE tag or spacer GIF. Let’s use the layout in Figure A as an example.

Figure A
Sample Web page layout

I’ll start by creating the header area. The code, which uses an inline style sheet for the sake of demonstration, should look like Listing A.

This code creates a 75-pixel tall, light blue area that has a 1-pixel black border on all four sides. To ensure compatibility with all three major browsers and to allow the layout to fill the browser window, I do not set a width attribute for the header.

Next comes the topnav area. To create this area, I update the code as shown in Listing B.

Just below the header is a dark blue area that has a 1-pixel black border around three sides. I don’t use a top border on the topnav because I’m using the header’s bottom border to divide the two areas. As with the header, I don’t specify a width for the topnav.

I add the leftnav next. The code now looks like Listing C.

Now there is a 200-pixel by 450-pixel gray bar running down the left side of the page. It has a 1-pixel black border on the left and right but not the top and bottom. It will use the topnav’s bottom border and the footer instead. Note that the leftnav uses the float attribute. By setting the float to “left,” the leftnav will always sit to the left of the element that comes after it. In this example, it will sit to the left of the body element.

After adding the body element, the code will look like Listing D.

The body area is 450-pixels tall with a 1-pixel black border on its right side. The body uses the topnav’s bottom border, the leftnav’s right border, and the footer to give the illusion of a 1-pixel border on all four sides. As with the header and topnav, I don’t use a width attribute on the body.

The final area of this layout is the footer. To create the footer, I add the code in Listing E.

Note two things about the footer. First, no border attributed is used. Since the footer and all of the other elements’ borders are black, there will be the illusion of a black border around the footer. Second, I use the clear attribute. With clear set to “none,” the footer will not be affected by the relative positioning of the other elements. For example, if the body element had used “float:left” (which would try to place the footer to the right of the body), the “clear:both” in the footer would override the float attribute and place the footer at the bottom where it belongs.

Navigation bar
Now that I’ve completed the basic page layout, I can use CSS2 borders to create faux buttons in the topnav area. Figure B shows what the final page should look like.

Figure B
Basic page layout completed

As with the page layout, all of the faux button effects can be created with CSS2. Listing F offers the code for adding the navigation bar.

Now a row of four buttons appears inside the topnav area. Each one has a 1-pixel black border on the right. The first button uses the border of the topnav area to create its left border. The other buttons use the right border of the button to their left to create their left borders.

I’ve used a “buttons strong” style to highlight the button that corresponds with the page the user is currently on. For example, if this were my home page, I would want to show the “home” button in a different style from the other buttons. Using the “buttons strong” style, I can create a distinct look for any button simply by placing a <strong> tag around the text.

Because the styles for the other buttons are applied to hyperlinks, I can use different link behaviors, such as hover, to trigger different styles. This allows me to create a mouseover effect that changes the button’s background from blue to dark gray when moused over. Without CSS2, this type of effect typically requires the use of two graphics, one for the default state and one for the mouseover state.

Site updates are easier
Not only does CSS2 result in cleaner code, but it also allows you to update your site faster and easier than HTML-only pages. Instead of having a bunch of hard-coded HTML pages that each need to be changed manually, CSS2 allows you to make site-wide changes by simply updating the style sheet. I used an inline style sheet in this example; however, you should use an external style sheet to get all of the benefits of CSS2.

For example, if you get tired of having a leftnav bar and want to try it on the right, you can just change the style information for the leftnav and the body. The changes will be reflected on every HTML page that uses that style sheet.

In addition, if you want to change the name of one of your buttons, you don’t need to create new button graphics. Just change the text in the HTML file.

So there it is—a cross-browser-compatible, CSS2 page layout with no tables, spacer GIFs, or button graphics that is simple to update.