Everything in its place…
The first time anyone designs a web page they want to get everything on the page laid out just right. Anyone who doesn’t limit their testing of a page to their own browser soon realises that this isn’t possible: the page is never going to look identical in two different browsers. Even so, the aim of giving a site a character which is recognisable across different graphical browsers is reasonable — but how to do it?
There are two basic approaches — one which has been in use for some years, so we might call it the traditional approach, and one which only became possible with the advent of CSS. Using CSS to position page elements is what we’ll be looking at here, for the most part. The traditional approach is, of course, using tables to define the layout — why shouldn’t we use that?
Tables
Using tables to lay out a page can allow very complex designs (with very
complex markup); it does not mean that the user need be aware that that is
what he is looking at (although there have been sites built with tables which
had visible, thick borders — very ugly, very 1997). Turning off the table
borders (<table border="0">) allows the designer to build
layouts as complicated as he might wish while the user sees (hopefully) a
clean page without a hint of the skeleton holding it together.
There are, though, problems with using tables to control layout. The first problem is that it goes against the entire concept of the way HTML is supposed to work. I know, I know — I’ve said this before (and before, and before… ). It bears repeating, however: HTML is supposed to define the structure of a web page — this is a heading, this is a paragraph and so on. It is not supposed to, and not designed to, define the appearance of a web page.
Having said that, for quite some time there was literally nothing else
a web designer could use but HTML, so it is understandable that anyone building
a web page would grab with both hands whatever was available to lay out a
page — <font> tags, the single-pixel GIF trick and using tables for layout being among the most widely used and abused.
The table element was never intended to be used for laying out a page. To state the obvious: the table element is for the tabular presentation of information. That is its sole legitimate function.
The second problem with using tables to handle page layout is a practical one: it is is hideously complicated. This is not so much a problem during the initial creation of the page, but it is when you come back to it to update or amend it. Picking out exactly which cell you should be fiddling with when there are scores in the page is extremely difficult, especially if there are several nested tables. Perhaps it would be all right if you simply avoided nested tables, you might think — except that sometimes nesting tables is the only way to make a table-based design “work” because the cross-browser results of using a single table are nowhere near as predictable as you might think.
The worst thing about table-based designs, though, is that they are based on the premiss that the only way to access the Web is using a graphical browser — and that is just plain wrong. There are people accessing the Web with user agents which can display nothing but text; these aren’t neo-Luddites clinging to ancient versions of Lynx (which is, by the way, still developed and every bit as modern a browser as MSIE or Mozilla), many of them are using cutting-age technology, i.e. handheld devices, to access the Web. There are also people who are blind and cannot view the Web at all, so they rely on text readers. Anyone who is not using a graphical browser may find pages held together with tables a hopeless, unintelligible jumble.
There was an argument, if not a completely compelling one, for using tables to design attractive pages when it was all that was available, but now we have something better. Leave tables for what they are good at — the tabular presentation of data — and leave HTML to do what it is good at, describing the page’s structure; leave the appearance of the page to style sheets. This way, you can produce a page which looks good in graphical browsers and is completely accessible to other user agents. What’s more, it is actually easier and faster than constructing complex tables for the layout.
Style sheets and positioning
I looked briefly at the use of style sheets to control the positioning of page contents in an earlier article on CSS where I gave an example of the style information which might be applied to an element <div id="Nav2">:
#Nav2 {
position: absolute;
left: 7px;
top: 339px;
width: 81px;
height: 260px;
z-index: 12;
overflow: visible;
visibility: visible;
}
What this means is that the div is positioned absolutely
on the page, its position being defined relative to the top and the left
edge of the page (assuming it is not inside another div, when the offset would be defined with respect to that): it is 7px from the left edge, 339px from the top; height and width are self-explanatory, but there are points about using these properties which we’ll come back to; overflow
determines what happens if the element’s content extends beyond the boundaries
of the element — we’ll be coming back to that, too; the visibility
property determines whether or not the element is visible (obviously) — this
is something which can be adjusted using JavaScript (an example of this can
be seen in the article on hiding and revealing parts of the page); z-index
is a number indicating how the layer relates in a notional three-dimensional
space to other layers on the page — layers with higher z-index values are “on top” of layers with lower z-index values.
Positioning an element using CSS means that the element is
treated as though it were a box on the page into which you can place content.
The positioned element does not have to be a div, but some browsers have problems if CSS positioning is used on other elements (and there are elements which it would be stupid to try to position: br comes to mind). The position property determines how the box is placed relative to other page content. There are four values you need to be aware of:
relative– the box is positioned as it would be in the normal flow of the document and then offset relative to that; another box following that in the normal flow of the document will be positioned as though the original box were not offset.absolute– the box’s position is specified out of the normal flow of the document, i.e. the box has no impact on the positioning of elements later in the document; it is placed in an absolute position with respect for its containing block, which may be the browser window or another positioned element.fixed– the box is positioned in the same way as withabsolute, but then is additionally fixed with respect to some frame of reference — in most cases, obviously, that is going to be the browser window.static– the box is laid out according to the normal flow of the document;leftandtopproperties do not apply. In other words, the box is not positioned.
To determine the offset from the element’s containing block (in the cases of absolute and fixed) or the element’s position in the normal flow of the document (in the case of relative) the properties left, right, top and bottom are used — in theory, anyway. In practice, few browsers currently available recognise right or bottom.
You can see absolute and fixed positioning in
use on this page. The page heading is positioned absolutely relative to the
edges of the page; the menu is fixed. Unfortunately, few browsers currently
support the fixed value, and that includes MSIE
6 which was heralded as having a new level of standards-compliance. Mozilla
(and, I think, recent versions of Netscape 6/7) does support it. Here is
the way this page looks when first loaded in MSIE 6 and Mozilla 1:
![[Image: Page in IE 6]](../../images/examples/msie1.jpeg)
![[Image: Page in Mozilla 1]](../../images/examples/mozilla1.jpeg)
Now see the appearance when it has been scrolled — in MSIE 6 the menu has disappeared, but it remains available at the right of the screen in Mozilla:
![[Image: Page after scrolling in IE 6]](../../images/examples/msie2.jpeg)
![[Image: Page after scrolling in Mozilla 1]](../../images/examples/mozilla2.jpeg)
It would be good if MSIE interpreted position: fixed as position: absolute but it doesn’t, so a kludge to position the element absolutely in MSIE is necessary.
Margins and padding
Talking about elements as occupying a box on the page is a simplification: more accurately, the element is in a set of containing boxes like so (this will only be visible if your browser has good CSS support):
The solid black line is the border of the element — that is, it is the line you would get if you included this property definition in the element’s style information:
border: 1px solid #000000;
The white space between the border and the element’s content is the padding; the green space between the border and the outer broken line is the margins. The width of the element is the width of the content (shown in blue); the width of the box is the full width, including the margins. Any background applied to the element will extend only as far as the border — i.e., it will extend into the padding, but not the margins.
Padding and margins can be set for specific sides of the element, using e.g. padding-top, or, by simply using padding and margin, for all sides of the element:
#element {
position: absolute;
top: 50px;
left: 50px;
width: 500px;
height: 400px;
margin-right: 50px;
margin-bottom: 50px;
padding: 30px;
}
The simplest way to apply a border to an element is to use the shortened syntax which combines border-width, border-style and border-color like so:
border: 2px dotted #990000;
You can also easily apply a border to one side of an element:
border-right: 1px dashed #660099;
There are nine possible values for border-style, one of which is none (the simplest way, though, to specify no border is with border: 0;). These are the remaining eight:
solid
dotted
dashed
double
groove
ridge
inset
outset
Each of these boxes has been defined with a border-width setting of 4px for clarity. The values solid, dotted, dashed, inset and outset will work down to a width value of 1px; the effects of double, groove and ridge
need a width of at least 3px to be apparent. Note that only a very standards-compliant
browser will display these borders correctly; a browser which does not fully
support the standards will show several of the other values identically to
the display of border-style: solid.
It is important to remember when laying out a page using CSS that the width of an element is the width of the content plus the padding plus the border thickness (twice, if the border is on both sides) plus the margins.
Overflow
What happens if the content of a div is too big for it? You may specify
height and width values which easily accommodate the desired text on your
browser, but that doesn’t mean the same will be true for other users. (If
you can’t see why, you should read the article on text on the Web.)
What happens in this case will depend on the value of the overflow property.
Again, there are four values you need to understand:
visible– the content is allowed to extend beyond the borders of the box.hidden– the content is “clipped” and no scrolling mechanism is provided, so the clipped content is inaccessible.scroll– scroll bars are provided whether or not the content is clipped (this may be desirable in a dynamic environment).auto– user-agent-dependant, but a scrolling mechanism should be provided where the content overflows.
Note that some browsers may handle the overflow values in an unexpected way — with visible possibly extending the box to encompass the content, for example. Here’s a page showing these values of the overflow property in action.
Failure to understand how this works can have embarrassing effects. Recently I was commenting in my weblog on a piece in a blog by Brendan O’Neill. I noted at the time that something had clearly gone wrong with the background colours of his page, as you can see from this screenshot:
![[Image: O’Neill’s page in Mozilla]](../../images/examples/bonmoz.jpeg)
Obviously his intention was that the pale yellow (#ffffcc) colour would form the background to the blog text and the two menus. I said this in my blog:
I’m going to take a stab in the dark and guess that in Internet Explorer the pale yellow background extends all the way down behind the main content and the sidebars.
I was right: here is a screenshot of that same page in MSIE 5:
![[Image: O’Neill’s page in MSIE]](../../images/examples/bonie.jpeg)
The problem is that MSIE does not simply render what it is given, it tries to guess what the author intended — something which is clearly going to produce unpredictable results, so it is wise not to rely on MSIE when testing pages (all you are proving whether they work in that particular version of MSIE). The source of the page O’Neill wrote shows this style information (edited for legibility):
.leftmenu {
position:absolute;
left:10px;
top:100px;
width:170px;
height:100px;
z-index:1;
background-color: #FFFFCC;
}
.blog {
position:absolute;
left:200px;
top:100px;
width:380px;
height:200px;
z-index:1;
background-color: #FFFFCC;
}
.rightmenu {
position:absolute;
left:600px;
top:100px;
width:170px;
height:100px;
z-index:1;
background-color: #FFFFCC;
}
As you can see, the overflow property hasn’t been specified, so it will default to visible. The problem is, O’Neill has specified a height for these div elements. Now, if you have a div containing an image and nothing else you can specify its height because you know the height it needs to be; where a div
contains text, though, you cannot ever possibly know what height it needs
to be. Certainly 200px is a bizarrely low value to accommodate a verbose
weblog (I do love the fact that the blog is allowed a whole extra 100px over
the menus), but setting any value is the wrong approach.
What O’Neill should have done was to set left, top and width and leave height undefined: that way the div
would expand vertically as required by the content. What he has done means
that any browser properly rendering the markup and style information he has
given it will draw the box, put in the background colour and allow the contents
to expand beyond the bottom of the div.
Fluid or rigid?
Once you have got the basic idea of how to position a page element and how to set its padding, margins and borders you are ready to think about putting some elements together to make a page. The first question you have to ask yourself is: do I want a rigid design or a fluid one? By rigid I mean that everything has a set width and stays in the same place relative to the rest of the page no matter what the user does to the browser window.
Let’s say, for example, that you make the width of the page 600px. You want to have an area for a menu or two and an area for the content. Here’s an example of a very simple 600px-wide layout.
I haven’t picked the figure of 600px at random. Quite a lot of sites design to about that width — see, for example, the BBC News site. [The BBC’s news site has been redesigned since then, and the content is no longer squeezed into 600px at the left of the window — but, although wider, it still uses a rigid layout with substantial white space at the right of the content in a window 1024px wide (by no means an exceptional size).] A figure of 800px may be picked — recently someone said on Usenet, “We all design to 800px, don’t we?” (Well, no…)
The rationale, such as it is, behind this approach is: the lowest resolution monitor anyone is going to be using is 640×480 — design to a width of about 600px and your design will not give such users a lot of horizontal scrolling (which is widely loathed); or: most people use a monitor of at least 800×600 resolution, so design to that and most people will be catered for while users of 640×480 displays will only have to do a little horizontal scrolling.
The problem is, it isn’t true. For one thing, the minimum resolution is not 640×480 — what about people accessing the Net from PDAs? For another, the screen area available may be 600px (or 800px) wide, it does not follow that that is the available width of the browser window. Another point is that most people now use monitors with higher resolutions than 640×480, and in that case the content occupies a 600px-wide strip down the left of the browser window with an expanse of unused space to the right of it. The unused space may be more than half the browser window in some cases! An 800px-wide strip is only slightly better.
A slightly better approach, if you insist on a rigid design, is to create a page with the, say, 600px-wide content area as before but centre the content in the browser window. Users of higher resolution monitors still have quite a bit of unused screen space, but this is much less obtrusive if the content box is in the middle of that space. Here’s an example of a 600px-wide, centred design.
It looks better than having a narrow strip of content down the side, but wouldn’t it be better if you could make use of the whole window, whatever its size?
Yes, it would, which was why that rhetorical question on Usenet got the answer: “No, we don’t.” We don’t design to 800px, or 1024px either — a lot of us try to design in such a way that the design adjusts to the window size: i.e., the design is fluid.
The basis of the fluid approach is not to rigidly define the widths of most of the page elements at all. If you have read the article on setting the size of text, you’ll immediately see the logic behind using a fluid approach: you have no control over how the user looks at your page (assuming that the user is “looking” at all) — what the screen resolution is, whether the display is 32-bit colour or monochrome, what size the browser window is, what fonts are available and what size text is displayed — so attempting to rigidly specify a page layout makes no sense.
So: suppose we take the very simple example page we have looked at already.
Instead of making the content area 600px wide, why not make it, say, 90%
of the page width (that will give a margin between the edge of the window
and the content area, which is good for usability). The width of the menu
box could be 12% of the width of the content box; the width of the box for
the text 80% — with padding-left: 20% that will give a decent
margin between the text and the menu; the menu box should sit “over” the
text box, so it needs a higher z-index value. Take a look at this example of a simple fluid design.
Fluid design, by making as few assumptions about the user’s browser as possible, allows the page to flow to fit the available space while giving the designer enough control to present it in an individual and appealing manner. Using CSS for presentation and HTML to define the structure also means that user agents other than graphical browsers — e.g. text-only browsers or audio text readers — can access the page’s content without difficulty. The only real argument for the old approach of using tables was that you could not rely on browsers supporting anything else. Times have changed. Once, Netscape had 70% of the browser market, the other 30% being composed of various other browsers; now browser stats suggest MSIE has over 80% of the browser market, with Netscape browsers down to under 10%. Of the versions of MSIE in use, 98% are version 5 or higher; about a third of Netscape users are using recent versions — which means that you can rely on most browsers in use being able to handle CSS positioning. It isn’t perfect — users of MSIE 6 are still not getting anything like the CSS support they should be, but it is certainly adequate to cope with basic positioning with CSS. The reasons which used to push designers into complicated table-based designs are dead: it’s time to kill those design techniques too.
Practical positioning with CSS
To summarise the important points you need to bear in mind when laying out a page using CSS:
- The width (or height) of the element is the width (or height) of its content plus borders, padding and margins.
- Absolutely positioned elements are positioned with respect to to the edges of their containing box — if they are children of the body element, that is the browser window; they are unaffected by the normal flow of the document and they do not impact on the normal flow.
- Elements positioned using the fixed value are positioned in the same way as absolutely positioned elements then fixed relative to a frame of reference (usually the browser window).
- Relatively positioned elements are offset (by the values of the left and top properties) from the position they would otherwise occupy in the normal flow of the document. Positioning of subsequent elements is affected as though they were not offset.
- The overflow property determines what happens when content is larger than the containing element.
Here is a series of examples showing the positioning of div
elements with the same dimensions and using the same left and top values
but varying in where they occur in relation to each other in the markup and
whether they are absolutely positioned (blue) or relatively positioned (yellow).
The example should help illustrate the way absolute and relative positioning
work, but the best way to learn about the intricacies of how it works is
to look at the W3C’s CSS specs, look at sites which use CSS positioning (see some of the further reading suggested below, for example) and to experiment with it yourself.
Caveat
The point needs to be emphasised that using CSS to position page elements is really only giving a suggestion to the user agent as to how the page should be displayed (where that has any meaning). The better browsers give the user a great deal of control over how a page is rendered, often allowing them to create user stylesheets to override the author’s CSS. This is the way the Web works, and there’s no use moaning about it. The point about the Web is that it allows the delivery of hypertext information — how that is presented is secondary to the fact that it is presented. Create flexible designs which don’t demand a certain combination of hardware and software to deliver the page and you can still give your pages an individual character without forcing users to override your suggestions and without putting obstacles in the way of disabled surfers or users of text-only browsers. Create rigid designs which depend on (a delusional) pixel-perfect layout and fixed, tiny fonts and the user will either go away or simply jettison the design you have laboured over.
The web comes with basic accessibility features designed-in: these features help all kinds of client … as well as those who have disabilities.
It’s remarkable to see the amount of extra work which some web designers invest to frustrate those basic design features and … keep disabled users out or at least make browsing pointlessly hard for them.
Further reading:
-
W3C: Cascading Style Sheets
http://www.w3.org/Style/CSS/ -
W3C: the Box model
http://www.w3.org/TR/CSS2/box.html -
Eric Meyer: CSS
http://www.meyerweb.com/eric/css/ -
DigitalWeb: Web Page Reconstruction with CSS
http://www.digital-web.com/tutorials/tutorial_2002-06.shtml -
CSS Layout Techniques: for Fun and Profit
http://glish.com/CSS/
© DC 2002. All rights reserved.


