Every time we’ve specified style="(something)", we’ve actually created a CSS rule. Although CSS (Cascading Style Sheets) is a different language from HTML proper, it is an indispensable tool for controlling the appearance of your website. Think of each webpage as having three components:

  • Structure: The markup is like the page’s skeleton. It provides the basic structure for the page: headings, sections, paragraphs, lists, and more. Without structure, your web page would just be an undifferentiated blob of text.

  • Content: The content (text, images, and even audio or video), is like the page’s flesh. This is the “meat” of the page. Without content, there’s nothing to read, and no reason to visit the page in the first place.

  • Presentation: The CSS is the page’s skin, hair, clothes, and makeup. Without presentation, your page might be readable, but it won’t be very attractive.

So far we’ve only been working with individual styles applied to individual elements. Although this works, it is not the most efficient way to apply our styles. A far better technique is to collect all our CSS rules in one place, a style sheet, and then apply the style sheet to every single element on the page… or for that matter, every single element throughout the entire website. Let’s see how this works.

Embedded Style Sheets

An embedded style sheet affects every element on the page. In order to create an embedded style sheet, we need to go to the head of the document. (Remember the head element? Finally, here’s something else that goes there besides the title element.)

Here’s an example of an embedded style sheet (please forgive the garish green-on-yellow):

Example 3.3. All Green Paragraphs

<html>
<head>
<title>When Irish Eyes Are Smiling</title>
<style type="text/css">
p {color: #008000; background: #ffff00}
</style>
</head>
<body>
<h1>When <em>Irish Eyes</em> Are Smiling</h1>
<p>
Here's how the chorus goes:
</p>
<p>
When Irish eyes are smiling,<br>
<em>Sure, 'tis like the morn in Spring.</em><br>
In the lilt of Irish laughter<br>
<em>You can hear the angels sing.</em><br>
When Irish hearts are happy,<br>
<em>All the world seems bright and gay.</em><br>
And when Irish eyes are smiling,<br>
<em>Sure, they steal your heart away.</em>
</p>
</body>
</html>

The syntax is a little different from what we are used to, but the core idea (the CSS rule) should look familiar. Let’s examine the style sheet’s components:

  • <style type="text/css">: The style element indicates the beginning of the style sheet. It must go inside the head. The type attribute specifies that you are using a CSS style sheet, as opposed to using some other, yet-to-be-invented style sheet language. It’s a bit silly, but the HTML specification requires it, so go ahead and add it.

  • p: The CSS selector. This says, “do something to all p elements.”

  • {color: #008000; background: #ffff00}: The CSS declarations. We’ve seen these before in the style element, although without the curly braces. Together with the selector p, the declarations constitute a CSS rule: “make all paragraphs green text with a bright yellow background.” As mentioned in “Background Color”, you must separate multiple declarations with a semicolon.

Note

You will almost always see people wrap their embedded CSS rules in an HTML comment, like so: <style><!-- p {color: #008000;} --></style>. This is an ancient convention used to hide all your CSS rules from browsers that do not understand CSS at all, namely Mosaic and Netscape Navigator 1.0. Fortunately, these browsers are long-dead, and wrapping your styles in comments is an empty ritual.

Now, we could have achieved the same effect by adding these declarations to the style attribute of each paragraph. The key difference is that the style sheet affects all paragraphs. The selector enables us to specify the declarations once, and the browser then applies them to all elements that match the selector.

Multiple CSS Rules and Selectors

You may specify as many rules as you like in a style sheet. Consider the following:

Example 3.4. Green Paragraphs, Red Body

<head>
<title>When Irish Eyes Are Smiling</title>
<style>
body {background: #ff0000}
p {color: #008000; background: #ffff00}
</style>
</head>
<body>
<h1>When <em>Irish Eyes</em> Are Smiling</h1>
<p>
Here's how the chorus goes:
</p>
<p>
When Irish eyes are smiling,<br>
<em>Sure, 'tis like the morn in Spring.</em><br>
In the lilt of Irish laughter<br>
<em>You can hear the angels sing.</em><br>
When Irish hearts are happy,<br>
<em>All the world seems bright and gay.</em><br>
And when Irish eyes are smiling,<br>
<em>Sure, they steal your heart away.</em>
</p>
</body>
</html>

Here we’ve specified that the body of the page should have a red background, while all paragraphs should have a yellow background with green text. This color combination is so awful that I am loathe to discuss this example further. Let’s move on.

The key feature of CSS rules is that they are reusable. We’ve already seen that we can use them to apply a set of CSS declarations to, say, all p elements. But it gets better ― we can also give a rule with multiple selectors. Just separate the selectors with commas:

element1, element2 { declarations }

This applies the declarations to both element1 and element2. For example:

Example 3.5. Green Paragraphs and Headings

<head>
<title>When Irish Eyes Are Smiling</title>
<style>
p, h1 {color: #008000; background: #ffff00}
</style>
</head>
<body>
<h1>When <em>Irish Eyes</em> Are Smiling</h1>
<p>
Here's how the chorus goes:
</p>
<p>
When Irish eyes are smiling,<br>
<em>Sure, 'tis like the morn in Spring.</em><br>
In the lilt of Irish laughter<br>
<em>You can hear the angels sing.</em><br>
When Irish hearts are happy,<br>
<em>All the world seems bright and gay.</em><br>
And when Irish eyes are smiling,<br>
<em>Sure, they steal your heart away.</em>
</p>
</body>
</html>

Now the green text and yellow background applies to paragraphs and level 1 headings.

So far, we’ve only seen simple selectors that just select a single element. However, you can design selectors to be more “choosy” than this. One of the most useful variations is:

element1 element2 { declarations }

This looks similar to Example 3.5, “Green Paragraphs and Headings”, but notice there is no comma between the elements. That one little comma makes a big difference. This rule applies its declarations only to element2s that are contained within element1s. Let’s see how this works:

Example 3.6. Green paragraphs, Blue ems

<head>
<title>When Irish Eyes Are Smiling</title>
<style>
p {color: #008000; background: #ffff00}
h1 em { color: #0000ff }
</style>
</head>
<body>
<h1>When <em>Irish Eyes</em> Are Smiling</h1>
<p>
Here's how the chorus goes:
</p>
<p>
When Irish eyes are smiling,<br>
<em>Sure, 'tis like the morn in Spring.</em><br>
In the lilt of Irish laughter<br>
<em>You can hear the angels sing.</em><br>
When Irish hearts are happy,<br>
<em>All the world seems bright and gay.</em><br>
And when Irish eyes are smiling,<br>
<em>Sure, they steal your heart away.</em>
</p>
</body>
</html>

This specifies em elements to be blue, if and only if they are contained within an h1. The em in the h1 at the top of the page turns blue, but the ems in the paragraphs below are unaffected.

We’ll see a couple more examples of useful selectors in “Classes and IDs”. For a complete list of selector syntax, refer to the CSS Portal's CSS specification.

Style Sheet Cascading

What happens when CSS rules conflict? Here’s where the “Cascading” part of Cascading Style Sheets comes in. The official rules are complicated, but they basically boil down to “whichever CSS rule is ‘nearer’ or ‘more specific’ wins.”

Returning to our song lyric example, let’s say we didn’t want the first paragraph to be in green text:

Example 3.7. One Green Paragraph

<html>
<head>
<title>When Irish Eyes Are Smiling</title>
<style type="text/css">
p {color: #008000; background: #ffff00}
</style>
</head>
<body>
<h1>When <em>Irish Eyes</em> Are Smiling</h1>
<p style="color: #000000">
Here's how the chorus goes:
</p>
<p>
When Irish eyes are smiling,<br>
<em>Sure, 'tis like the morn in Spring.</em><br>
In the lilt of Irish laughter<br>
<em>You can hear the angels sing.</em><br>
When Irish hearts are happy,<br>
<em>All the world seems bright and gay.</em><br>
And when Irish eyes are smiling,<br>
<em>Sure, they steal your heart away.</em>
</p>
</body>
</html>

The first paragraph has black text. Our style attribute is more specific than the general page-level CSS, and so the black-text rule overrides the green-text rule. However, the paragraph still has a yellow background. The yellow-background rule cascades down to this paragraph, because we didn’t specify anything about it.

Another important cascading rule is that parent elements apply their style to their children (enclosed elements). Rules applied to the body element cascade down to enclosed p elements, rules applied to p elements cascade down to enclosed em elements, and so on. In fact, we saw this form of cascading in Example 3.4, “Green Paragraphs, Red Body”. The background of the page is red, and any child elements also have a red background… except for paragraphs, which specifically override this rule.

Reusable Style Sheets

What’s better than applying styles to an entire page? Applying it to an entire website.

CSS enables you to place your style sheet in a separate file. The stylesheet then becomes a central repository of CSS rules that you can apply to any page in a site. There are two ways to “call” a global style sheet into a given page:

Example 3.8. Global Style Sheets: The “link” Method

<html>
<head>
<title>When Irish Eyes Are Smiling</title>
<link rel="stylesheet" href="/css/style1.css" type="text/css">
<link rel="stylesheet" href="/css/style2.css" type="text/css">
<style>
p {color: #008000; background: #ffff00}
</style>
</head>

Example 3.9. Global Style Sheets: The “@import” Method

<html>
<head>
<title>When Irish Eyes Are Smiling</title>
<style>
@import url("/css/styles3.css");
@import url("/morecss/styles4.css");
body {background: #ff0000}
p {color: #008000; background: #ffff00}
</style>
</head>

The two methods have bizarrely different syntax, but functionally they are similar. They both allow you to specify multiple stylesheet files, and you may use them both in conjunction with an embedded style sheet.

Tip

One key difference is that the “@import” method is not supported in some older browsers, such as Netscape 4. This is actually an advantage, because you can use this to selectively hide styles from Netscape 4. This was a very useful trick several years ago, but as Netscape 4 disappears, it’s becoming much less relevant.

A linked style sheet also affects the rules for cascading:

  • A rule in a linked style sheet has low priority.

  • A rule in an embedded style sheet has medium priority.

  • A declaration in a style attribute has high priority.

This means you can specify a style in a linked style sheet, override that style for a particular page, and then override it again for a particular element. For example, if we have the page:

<html>
<head>
<title>What is your favorite color?</title>
<link rel="stylesheet" href="/css/style.css" type="text/css">

<style>
em {color: yellow}
</style>
</head>
<body>
My favorite color is <em style="color: blue">blue</em>.
</body>

and the linked stylesheet “style.css” contains:

em {color: blue}

then the browser uses the following logic to color the em:

  1. The linked style sheet specifies the em to be blue.
  2. The embedded style sheet specifies the em to be yellow, overriding the linked style sheet.
  3. The style attribute specifies the em to be blue again, overriding the embedded style sheet.

So the resulting color is “blue”. Whew.

 

See Also