CSS 101

CSS 101

Got something to say?

Share your comments on this topic with other web professionals

In: Articles

By Mark Newhouse

Published on August 11, 2004

In the TABLEs, spacer GIFs and FONT tag soup way of designing Web pages, most of the questionable techniques were concerned with issues of typography and white space. As we begin the process of understanding Cascading Style Sheets (CSS) we’ll look at these issues.

Extreme Resumakeover

A vast majority of Web sites are text-based. We have learned to embellish them with images and rich media, but the primary means of communication on the Internet is still the written word. This is especially true of a resume.

In this article we’ll take a look at a typical resume that has been marked up with valid and appropriate XHTML and apply some CSS to enhance the presentation.

Here is a “before” and “after” look at the resume. Both have identical markup, the only difference is that “after” has had a style sheet applied to it.

The site before and after applying CSS

The new school is old school

In the days before spacer gifs and FONT tags, there wasn’t much you could do to embellish the look of a Web page. As more presentational tags and HTML “hacks” came into use, we were given some additional control over how our pages looked. But these techniques were rather limited, allowing for control over only color, size and typeface with any consistency.

With CSS we can control all of that, and more.

Take a look at the markup of the resume. There are headings, paragraphs, links, unordered lists and definition lists—all pretty straightforward markup. And looking at the page in a browser presents a readable, albeit plain-looking, page. But we can do better.

The goal of a resume is to present the prospective employee to the employer in the best possible light. It needs to be readable, highlighting the person’s achievements, without being too distracting. CSS is the perfect match for the job, so to speak.

Horizontal white space—modifying the BODY

The first thing I notice is that the line length varies with the width of the browser window. Not a problem at small widths, but it becomes problematic at larger window sizes. This is something that CSS can do without having to add a TABLE to the markup.

We can use CSS to control the width of the text, making it more readable—an important consideration for a resume. We’ll start by modifying the presentation of the BODY. The CSS looks like this:

body {
margin-left: 7%;
padding-left: 5%;
width: 80%;
max-width: 700px;
background-color: #fffffa;
color: #333;
font-family: Arial, Verdana, Lucida, Helvetica, sans-serif;

The above is called a rule. It consists of a selector (body) and a declaration block, which is everything between the curly braces, inclusive. The declaration block contains one or more declarations, which, in turn contain a property-value pair. In the above rule there are seven such pairs, margin-left: 7% is the first of them. margin-left is the property and 7% is the value. Declarations are terminated by semicolons (;).

Let’s break down the above rule.

The first property in the rule is margin-left. It controls the left-hand margin of the BODY. You can also set values for the other margins, and you can use a short-hand method to set all four values in one declaration. In this example, the top, right and bottom values default to the browser’s internal style sheet values.

You can control the margin-left property with percentages, as I have done here, or with ems (em), exs (ex), inches (in), picas (pc), centimeters (cm), millimeters (mm) or pixels (px). Feel free to grab these files and change things to see how it affects the presentation of the page.

The next property is padding-left. This is very similar to the margin, and the same units can be used when setting its value. In a future article we will look at the box model, which will help clarify the difference between margin and padding. For now, think of margin as the space outside of the containing box, and padding is the space inside. I’ve defined both here to appease Internet Explorer for Windows.

The next property is width. It can accept the aforementioned units for its value, too. I have chosen to use percent, creating a fluid layout. The width will grow and shrink as the browser window is resized.

But there may be times when 80% is too wide. This brings us to the next property, max-width. This is set to 700 pixels—note that there is no space between the number and the unit. This particular property is not supported by all browsers. For those that understand it, the width of the BODY will never exceed 700 pixels. For those that don’t understand it, the width will always be 80% of the browser window. You can also set a minimum width via the min-width property.

The next two properties deal with color. I’ve set the page’s background-color to a hexadecimal number #fffffa. This starts with an octothorpe (#) and consists of 6 hex numbers. A hexadecimal number is a number in base 16. Hex numbers range from 0-9 plus 6 more as letters a-f. Zero is black, and f is white. Other acceptable values are RGB color values, expressed as either percentages of red, green and blue: rgb(100%, 100%, 95%) or expressed as a number from zero (black) to 255 (white): rgb(255, 255, 250).

The next property, color, sets the color of the text on the page. In this value I’ve used a short-hand hex number. If only three digits are used, then the browser doubles each number, so #333 is equivalent to #333333. As we’ll see later on, this value can be overruled by a subsequent rule in the style sheet.

See http://www.w3.org/TR/css3-color/ for more details on colors and color value equivalents.

The last property in this rule is font-family. This sets the default font for the page. The reason for the list is that not every computer accessing the page has every font available to it. Each operating system (OS) comes with a set of default fonts, but even OSs from the same vendor can change their default set over time. The ones I used in the rule cover some common sans-serif fonts that are found on Windows, Macs and Unix/Linux machines. The browser will check for the first font on the machine and, if it is there, it will use it. If not, then it checks for the next one in the list, and so on. The last value tells the browser to use the user-defined sans-serif font if it can’t find any of the fonts listed in the declaration.

So, here is what we have when we apply the rule for BODY to the page.

Typography and color—modifying the headings

Next I’d like to set the headings apart from the rest of the text. We can do this in a number of ways. The next rule will introduce a few new properties.

Here is the rule:

h1, h2, h3, h4, h5, h6 {
text-indent: -0.75em;
letter-spacing: 0.1em;
text-transform: uppercase;
margin: 1.5em 0 0 0;
padding: 0;
font-family: 'Trebuchet MS', Helvetica, Geneva, Arial, sans-serif;
color: #337;

The first thing you’ll probably notice is that there are several selectors. Each selector is separated by a comma, and each declaration in the rule will be applied to all of these selectors. In this case these are all the headings available to use in (X)HTML.

The first property is text-indent. This can have a negative or positive value, with the same units as margins and paddings, etc. I’ve set the value to -0.75em. This moves the heading to the left by 0.75ems. I chose to use ems because they are based on the size of the text. Since H1s are larger than H3s, they will be moved farther to the left, creating a visual hierarchy to the page. Note: it is this property that gives IE for Windows problems. If the containing element (in our case the BODY) does not have sufficient padding, any text that falls outside of the containing element will be cut off. This is why we set both margin and padding for the BODY.

The letter-spacing property allows us to control the space between letters in a word. Positive values increase the space and negative values decrease the space, squishing the letters together. I’ve elected to space things out, and used ems, which has the effect of making the spaces bigger on the larger headings.

The text-transform property allows you to make some changes to the text itself. You can force uppercase or lowercase, or capitalize each word. A value of none will reset any value that may have been applied in a previous rule.

We have already looked at margin and padding. In this rule I have used the short-hand version in the declaration. For margin I’ve set all four values, starting with margin-top and moving clockwise through the rest. The declaration is equivalent to the following four declarations:

  margin-top: 1.5em;
margin-right: 0;
margin-bottom: 0;
margin-left: 0;

In the padding declaration, since only one value is given, all four are assigned the same value, in this case, 0. Note that a value of 0 does not require any units.

Additionally, I have changed the font-family for all headings, and also changed their color. Since this rule appears after the BODY rule, these values will be applied, but only to the headings.

This is what it looks like when we apply both rules to the resume.

Vertical white space—modifying paragraphs and lists

When we made the changes to how the headings are presented, we used the margin property to control the top margin, setting it to 1.5em for each heading on the page. We also set all the other margins and padding to 0. When you look at the resulting page in a browser you might expect all the text underneath the headings to appear butted up against the bottoms of the headings, but that is not the case. This is because each browser has its own internal style sheet that it uses if there is no style sheet applied to the document, and in these style sheets there are default values for such things as margin and padding, as well as font faces, sizes, colors, etc. for each element (paragraphs, list items, etc.)

These default values often vary from browser to browser, so they need to be set explicitly if you want to have your page appear identically in every browser on every platform. It is good to get into the habit of setting both padding and margin as sometimes one browser will use margin and another will use padding in their internal style sheets to control white space. This is particularly true when it comes to how browsers create the indents for lists.

That said, let’s clean things up a bit to make the paragraphs and lists a bit more readable. At the same time we’ll line things up on the left side of the page.

Here are the new rules:

p {
margin-top: 0.35em;
margin-left: 0;
padding-left: 0;
line-height: 1.5em;
ul {
margin-top: 0.35em;
margin-left: 1em;
padding-left: 0;
li {
line-height: 1.5em;
dl {
margin-top: 0.35em;
dt {
text-indent: -0.5em;
color: #339;
margin-top: 1em;
dd {
margin-top: 0.35em;
margin-left: 0;
padding-left: 0;
line-height: 1.5em;

We are already familiar with most of the properties we’ll see in these rules. And you’ve probably noticed that the values for these properties are very similar across all the rules. This is because I want there to be consistency in the way the paragraphs and lists are presented on the page. Giving them the same values in the style sheet will ensure that that happens.

First I wanted to move the content under the headings up a bit closer than their default margins had them. So each property gets a top margin of 0.35em. Well, almost every property. List items (LI) do not have their top margins set, and definition terms have a different top margin measurement. For the LIs, the UL property sets the top margin. Setting a top margin for LI would also affect every list item, and I only want the top of the list to have the 0.35em margin, so I set it in the rule for the UL. I’ll explain my reasoning for the definition list rules shortly.

To finish up the rule for paragraphs, I set margin-left and padding to 0. Since the headings all have a negative text-indent, this makes the paragraph look like it is indented a bit, giving the page a visual hierarchy. I also wanted more separation between the lines of text within the paragraph. This is defined by the line-height property, which functions similarly to leading in print. It accepts the same units as margins and padding.

The next rule defines the presentation of unordered lists. Lists are unique elements, as they have bullets (or numbers, for ordered lists.) These bullets lie within the padding or the margin of the list, depending on the browser. So, we need to set both margin-left and padding-left to make sure our lists are presented in the same way across browsers.

In this case I wanted the bullets to line up visually along the same vertical line that the paragraphs do. Setting both the margin-left and padding to 0 moves the start of the text to that vertical line, and puts the bullet out too far to the left. We have to add 1em somewhere to get things to line up correctly. It doesn’t matter if you put it in the margin or the padding, you’ll get the same visual result for this example.

The list items are still too close together for my taste. There are a number of ways to add some vertical white space. Margins and padding are certainly options, but I want there to be a bit more separation within the LIs when they wrap, not only between the list items. This is why I chose to use line-height to control white space within the LI. To keep things consistent I used the same value as I did for the paragraphs.

This brings us to the definition lists. Visually, I want the terms (DT) to appear a bit like the headings so I have given them a small, negative text indent and the same color as the headings. To keep them distinct from the headings, I have not applied a text-transform. Additionally, I wanted a bit more separation, particularly within the list, so I added a top margin of 1em, which overrides the 0.35em top margin of the DL.

The definitions (DD) get the same rule as the paragphs. To save a bit of bandwidth we could have combined the two rules together like we did for the headings—something like this:

p, dd {
margin-top: 0.35em;
margin-left: 0;
padding-left: 0;
line-height: 1.5em;

Here is what things look like with the styles for the paragraphs and lists defined.

Details, details—class and id

This document is starting to look finished. There are just a couple of details that will complete the look. At the bottom of the resume is a list of jobs with the corresponding dates of employment. The dates are important, but detract from the more important job descriptions. It would be nice if there was a way to flag these short paragraphs in the document and tell the browser to display them at a smaller size, and perhaps in a more subdued color. Decreasing the vertical white space would also be nice. You’ve probably guessed by now that CSS allows us to do just that.

Further, there is another date at the very end of the document that indicates when the document was last modified. It would be nice to further differentiate that date, as well.

Here is what the rules look like:

p.date {
color: #999;
font-size: 0.8em;
line-height: 1em;
p#update {
font-style: italic;
text-align: right;

These two rules introduce a couple of new ideas—class and id. These are ways of targeting specific instances of elements that have the class or id assigned to them in the (X)HTML.

To get the above rules to apply to the resume, we have to make a change to the XHTML document. For each paragraph containing only a date or date range, we give it a class of date:

<p class="date">September, 1999-Present</p>

This enables the selector p.date to apply to those paragraphs with a class of date. Use class when you have more than one element that you want to apply the class to. If there is a unique element that needs a special presentation, it should have an id:

<p id="update" class="date">August, 2004</p>

As the example indicates, elements may have a class and/or an id assigned to them.

Remember that you can have only one element with a given id. If you want to assign more than one element the same special presentation, use class, as we did with the dates.

In the CSS, you will create a new rule that addresses the class by appending a period, followed by the class name, to the selector. In our example that looks like the first rule: p.date.

Here we’ve changed the color to a light gray, reduced font-size to 0.8em and reduced the line-height as well. Since it is a paragraph, it also inherits all the other properties that we didn’t explicitly change in this rule.

The other rule defines what paragraphs with an id of update should look like. The selector has an octothorpe followed by the id name appended to it (p#update). In our example I’ve given it a font-style of italic. Other acceptable values for this property are normal and oblique. To make text bold, use font-weight: bold;. I’ve further differentiated this paragraph by aligning it to the right via the text-align property. This property accepts values of left, right, center and justify. This paragraph will also inherit any styles not explicitly set by the date class or the update id, since it has both assigned to it in the XHTML.

Here is what things look like after adding these classes and the id (the link jumps to the end of that page so you can see the changes.)

Putting it all together

Now that we have an (X)HTML file and the CSS, how do we get the browser to apply the style sheet? There are several ways to do it.

First, you can apply the CSS inline using the style attribute on any tag. In our example we’d have to do this on every tag to get the CSS to work, so we won’t use that method.

You can also include the CSS in the HEAD of the document. You simply place it between STYLE tags like so:

<style type="text/css">
selector {
property: value;

This is particularly useful when you are first working on a page design as you can move back and forth between the (X)HTML and CSS within the same document as you try different combinations. This is the method I have used in the examples for this tutorial. Once you have nailed things down pretty well, I recommend using the third method, explained below.

This also happens in the HEAD of the document. Instead of including the style sheet, link to an external file:

<link href="cv.css" rel="stylesheet" type="text/css" />

The href points to the CSS file. The rel tells the browser what kind of link it is, and the type tells it what kind of style sheet is being linked. All three are needed in the LINK tag. By using an external file you can link multiple documents to the same file. This is extremely powerful as you can make changes across an entire Web site by editing a single document.

Build something

Now you have all the tools you need to apply some style of your own to your (X)HTML documents. And we have only scratched the surface of what can be done with CSS. Look for future articles introducing the box model and positioning. But don’t wait, go try it now!

Related Topics: CSS, Basics, Typography, Web Design

Mark Newhouse is the Web Designer for the National Optical Astronomy Observatory where he is fully aware of the unrealized potential of CSS. He enjoys the challenge of creating sites that use standards, look good, and work across browsers and platforms. Including Netscape 4 on Unix.