Web design: design and layout
Formatting your text
As you've seen above, you can define and attach styles to just about any
HTML you like from the broadest level (<body>) to an individual
tag using an #id. CSS2 offers impressive control over text formatting,
from colour to size or numbering style for lists. You can change the case
of letters, control the first line or first letter separately (to create drop-caps
or lead-ins), and modify the spacing between lines.
Aligning text
The text-align: property defines where on the current line your text should appear. The valid values are left, right, center, and justify. The first three should be fairly obvious; each line will attach to the left or right hand sides, or be centered on the screen. Using a value of "justify" varies the spaces between each word so that each line is the same length. For example, the main content of this tutorial uses justified text.
Choosing a text-alignment is often as much a matter of taste as good style. However, keep these guidelines in mind:
- Don't center or right-align blocks of text with long lines.
- Each line of a centered block starts in a different place, which makes the text harder to read. Centering works on headers, poetry, and other short blocks. Right-align can look better for addresses in letters, small lists that follow the left hand edge of the screen (like menu lists or credits)
- Justified text isn't always easier to read
- Don't justify narrow columns, or columns with regular long words - if only a few words fit into the current line, the space between each word will become very large. Justified text can be visually appealing, however. You could do worse than to give it a go.
An example:
#maintext { text-align: justify; }
#menu { text-align: right;
Perhaps confusingly, the text-align property also applies to images
you insert inside the block, unless you specify additional rules that specify
otherwise. So to center an image on screen, put it into a block (i.e., a paragraph
or division) that has the rule text-align: center;.
Fonts and font-sizes
Web browsers define several default font types with generic names that you can use in your style-sheets. These names are serif, sans-serif, mono-space, cursive, and fantasy. Serifed fonts have flared ends on the letter shapes (like feet at the bottom of the letter p), and the most popular serif font is "Times New Roman", also known simply as "Times".
On screen there just aren't enough pixels to draw serifs correctly at small point sizes (8-12pt) so sans-serif fonts are more readable but usually less visually appealing. If you want your site to be highly readable, use serif fonts only for large text and sans-serif fonts for normal/small. When printing, the roles are reversed: serif fonts are more readable on paper at low point-sizes and sans-serif is better for larger text like titles. Fortunately with CSS you can take this into account:
body, td { font-family: sans-serif; }
h1, h2, h3, h4, big { font-family: serif; }
@media print {
body, td { font-family: serif; }
h1, h2, h3, h4, big { font-family: sans-serif;
}
}
The first two rules tell the browser to use the default sans-serif font (usually
Arial) as the default font for the document, and to use the default serif
font for section headers and big text. The rule-block that starts on the third
line only applies if the document is being displayed by a printer, and its
additional rules replace the first two. Note that some older browsers (namely
Opera 6) don't correctly inherit the font size or type from the body into
tables, hence the td in the rules above. Tables are covered in
the advanced techniques section, so if you don't use them you can safely skip
them in your style-sheets).
Both Internet Explorer versions 5 and 6 suffer from a bug which prevents them resizing text if you specify an explicit size (like 14px or 12pt) in your style-sheet. In any case you should not specify a default font size. Readers with visual impairments often change their default font size to something larger than average, and some people prefer to shrink the default font to fit more text into the frame. As a web designer you need to take these preferences into account. The way to do this is to give your font sizes as relative to the default font size using ems or percent, and don't specify a default font size using absolute measurements. Here are three ways to specify resizable fonts in CSS:
h1 { font-size: x-large; }
.specialoffer { font-size: 1.2em; }
#maintext { font-size: 80%; }
This way you can define a style for your page without interfering with the preferences of your visitors. Unless you feel strongly about the kind of fonts you want to use, stick to the generic "serif" or "sans-serif" types.
The first line of the example above also shows a special set of sizes just for fonts. These sizes might look like absolute sizes, but their size is relative to the default font size and range from: xx-small, x-small, and small on one side, to large, x-large, and xx-large on the other. The benefit of using these names is that xx-small is supposed to never become unreadable. It has a lower size limit. Limiting the number of different font sizes you use generally makes a cleaner layout and is a great idea if you plan to accommodate handheld browsers.
You can specify several fonts in your order of preference if you like, and finish the list with one of the generic types so that if a visitor doesn't have any of the listed fonts, they still get roughly the right style. Avoid using the cursive and fantasy font families since most computers don't actually come with default fonts in these styles (Windows' idea of a cursive font is often Comic Sans, and it has no script font by default). The fantasy font type is so vague that it should be avoided: almost any font might be used, regardless of readability.
Put fonts with long names in quotes:
body { font-family: "Gill Sans MT",
Tahoma, Verdana, sans-serif; }
h1, h2, h3 { font-family: Georgia, Palatino, "Century
Schoolbook", serif; }
Line height and width
In CSS you don't specify line-spacing as such, but you specify the
height of the line instead. Lines are considered to be a lot like small blocks
in CSS, so you specify the properties of the lines and not the gaps between
them.
The default height of a line is about 1.2em (or 120%), leaving a fifth of
a line between lines. If you think your visitors might print your page, you
may want to do them a favour and not spread your lines too far apart, but
on-screen some wider line-spacing can make your text more readable. Don't
go wild though - too much space between lines and some visitors (especially
those with reading disabilities) can get lost. On screen, 1.4em is a nice
balance for large blocks of text. Your navigation and other visual elements
might be better off at the default line-height though. In this example, the
main content of your page has the id "maintext". This is what the
Bob's Bits example site uses.
@media screen {
#maintext { line-height: 1.4em; }
}
Flowing text around images
By default, when you insert an image into your HTML, its bottom edge lines up with the bottom edge of the line of text it's on. If you want to insert an image into a paragraph, you can "float" it. Floating an item removes it from the current flow of a block and aligns it to either the left or right hand side. You can float almost anything, not just images. This is a good way to add a visible caption to an image. This is the way that Bob's Bits displays a subtitled image on its "What are sprockets?" page. First the image section HTML looks like:
<span class="insetimage"><img src="images/notsprocket.jpg"
width="243" height="242" alt="(An image of something
that isn't a sprocket)"><br>
This is not a sprocket</span>
Then we define "insetimage" in our style-sheet:
.insetimage { float: left; background-color:
black; color: white;
line-height: 1.2em; font-size: 80%;
}
The result looks like this:

You can float entire blocks off to one side of the screen; if you want the main text or navigation of your site to attach to one side, float it.
Arranging your content
We've just seen how to change the appearance of text and images with general and specific styles, modifying how they look. Now we'll see how CSS can also specify where blocks appear on screen (if at all), and what colour they are.
Choosing your colours
Choosing a colour-scheme (and sticking to it!) can be very tricky. The wrong kind, or simply too few colours can make a page dull and lifeless, and too many colours can make the page seem garish and tacky. Furthermore the colour scheme you choose will not please everyone, whatever you do. In some countries in the east, bright, garish colours signify good fortune whereas in the US and the UK this is more likely to look tacky and unpleasant. Gambling sites like Ladbrokes vary the colour scheme of their site to match the geographical locations of their visitors.
Even more awkwardly, some colour combinations can make your site utterly unreadable to sufferers of various forms of colour-blindness (one in every ten men reading your site has some form of colour-blindness). Consider your audience and the nature of the content before you choose your colour-scheme:
- Choose appropriate colours. Pastel colours, particularly shades of blue, are generally soothing.
- Bold, bright colours can strain the eyes after a while. Avoid both white-on-black and black-on-white: they glare and tire the eyes. A good background colour for dark text is a pale cream (#EAEAE0) or very light gray (#EAEAEA).
- Reds, yellows and browns are "warmer" colours; autumnal, while pale pastelly blues are wintery, cold. Don't choose colours that go against any mood your content may have.
- Four colours for your layout is a good guideline. You need a general background colour, a general foreground color, and a couple of accent colours. There are a few examples in the slideshow image below; you can generally build a fine looking site with just four to six colours (BBC News Online has 6).

To set the colour of default text, you should modify the body
element. Links have several pseudo-elements that are described later,
but the basic modification should be on the a (anchor) element:
body { color: black; background-color:
#EAEAE0; }
a { color: RGB(60,50,90); font-weight:
bold; }
a:visited { color: RGB(50,40,80); }
a:hover { color: RGB(180,50,50); }
The above styles make normal text black on a cream background. Links are shown in bold, deep purple. Visited links are slightly darker so your visitors know which links they've recently followed, and while the mouse is over a link, it becomes a brighter red.
Boxes, borders, padding, and margins
Before we go further and describe how to set the size and style of this block,
we'll cover how CSS draws blocks on screen. There are a handful of ways to
fit your content into a column. In all of them you need to define what content
fits in the column, and if you cast your minds back to the Bob's Bits template,
you'll remember the <div id="maintext">...</div>
section. The purpose of this was to group your main content into a block to
which you can apply a style..

When you specify the width and height of a box, you only define the size
of the content area, which is the content plus padding. If you don't specify
padding then the content will fill the width you specify, right up to the
edges. Outside of the width and height you specify, the browser draws the
border (if you specify one), and the margin (again, if you specify one). Most
block tags have pre-defined margins which you can change if you wish. If you
want to render a standard block like h2 or even body
with a border, margins and padding, you can simply define a style just like
any other block you create with a div tag:
body { border: thick solid black; padding:
1em; }
If you do not specify a width and height, the browser will guess the correct
size to fit in the amount of content you provide. You can provide just
a width, or just a height, but if you specify a height and no width,
the width is assumed to be inside the width of the browser window. If you
specify a width and height and the content doesn't fit inside, it will usually
just "leak" out of the bottom. If you use the <pre>
tag or a long run of text that doesn't wrap to a new line, it'll escape
from the right hand side too. In your style-sheet you can specify other behaviours
for this. The default is "visible", but you can also specify "scroll",
"auto" and "hidden". Remember that you can add more than
one rule and the browser will choose the latest one that it supports, so:
#maintext { overflow: auto; overflow:
scroll; }
The properties you can set on a border are its style, its width, and its colour. You can set these for all four sides of a block, or for individual sides. Because of the way CSS works, you can even specify a property for all four sides, and then a property to draw one of the sides differently. To set border properties for all four sides of a block, you can use the three border properties: border-width, border-style, and border-color. To make life a little easier on you, you can also use a shortcut property called border. This property takes the same values as the other three and guesses what you mean. So:
#maintext {
border-style: solid;
border-width: thin;
border-color: black;
}
... is the same as...
#maintext { border: thin solid black; }
If you want to set the properties for just one side of a block, give its name in the property:
#maintext {
border: thin solid black;
border-bottom-width: thick;
}
The same conventions apply to margins and padding, however the only property is width. The following rules are all valid:
#maintext {
padding: 0.5em;
padding-bottom: 10px;
margin: 0;
margin-left: 10%;
margin-right: auto;
}
Note that no unit is given on the fourth line (margin: 0;) which is usually a problem, except that 0 is 0 in any unit supported by CSS.
Columns, boxes, scrolling
Columns are a good idea. True newspaper-style columnar layouts are virtually impossible right now (CSS 3 will have them) because it's not possible to gauge the width or height of a particular browser's window. However, confining your main text to a single column and putting site navigation in second column to one size or bar at the top & bottom makes your content easier to read. The most readable width for a line of text is around 10 to 13 words, and most desktop browser windows are much larger than this.
With CSS you can position blocks in the following ways:
- static positioning
- The block sits in the document exactly where you declare it. This is the default.
- relative positioning
- With this method the block is positioned relative to its static position in the document
- absolute and fixed positioning
- To position the block in a forced, fixed position. With absolute positioning, the block is placed relative to the block it's declared in (or the document body if it's not in another block), whereas with fixed positioning, the block is placed on screen relative to the web browser window and it stays fixed there even if you move around the document. Unfortunately, Internet Explorer 5 and 6 don't support fixed positioning and will fail to position your block correctly. Since (at the time of writing) IE accounts for about 95% of site visits, you should not use fixed positioning in your style-sheets. You can specify a z-index property to handle which block is on top if two blocks overlap.
Absolute positioning gives you the greatest control over your layout, allowing you to draw items on screen in a different place and order than their positions in the HTML code, but static positioning is the best-supported method among the various web browsers. Fixed positioning is handy for making sure your navigation is always on screen. To position your maintext section as a column on your page, you must specify its width. If you use static positioning you need to specify margins too, else the block will just fill up the available space (you don't have to worry about this if you use absolute positioning). However, by positioning an element absolutely, you are removing it from the document flow (just like floating an image like we saw earlier) You need to be careful you don't cover up text beneath absolutely-positioned items. Either position the other content absolutely too, or make sure you set a "clear" property on them so that they won't draw unless there's room on the left, or right, or both:
.anotherblock { clear: both; }
Even though the wording of "absolute positioning" suggests that your block will be fixed, you can still specify relative sizes and positions in percentages of the browser window's width, and give minimum and maximum sizes.
Here is a static example which is what the Bob's Bits example site uses. Because static positioning is the default, you don't have to set the position property, but it's included here for the sake of completeness. The column will always be at least 400 pixels wide, but never more than 75 exes (an ex is the height of the letter x, which is close enough to the average width of a letter on most fonts. The average length of a word is 5 letters, the longest line we want to allow is 15 words). The column appears in the centre of the window because the left and right margins are set to automatically fill up the gap between the edge of the content and the surrounding block. Specifying a minimum width can be tricky because of low resolution mobile devices: you don't want to force them to show a column that's wider than the width of the screen because visitors will have to scroll left and right as well as up and down. Remember that there is a "handheld" media-type for CSS which lets you give special rules just to mobile devices. You could use that to stop browsers using the minimum width (and forcing horizontal scrollbars).
#maintext {
position: static;
width: 70%; min-width: 400px; max-width:
75ex;
margin-left: auto;
margin-right: auto;
}
Here's an absolutely-positioned example. As you can see, you do not need to specify left, right, top and bottom positions: you can specify width and height instead of two of the sides. Here we put the column 25 pixels away from the top right hand side of the browser window, then make it extend 60% of the screen width or a maximum of 75ex again as above. Remember to specify a height (even if it's just "auto") when you position absolutely because otherwise the height will not extend past the bottom of the browser window on some browsers, and that's the kind of thing you'll only notice if the column has a different background colour than the surrounding document.
#maintext {
position: absolute;
top: 25px; right: 25px;
width: 60%; max-width: 75ex;
height: auto;
}
Because the "maintext" block is declared inside the body section,
and not inside another block deeper in the structure, the "top"
and "right" positions are from the browser window. If you want to
attach a block right to the edge of the browser window, remember that even
body has some padding by default.