Looking for the lessons? Get started!
The functions of CSS selectors, attributes, and values.
The entire Web Design Principles section can be accessed through the menu below.
Unfortunately, not everyone’s browser will support the spiffy JavaScript menu behind that innocent-looking button. If your browser won’t display the menu, just click on the button and you’ll be taken to a separate page with the entire menu displayed in clear, non-JavaScript HTML.
But one of the attributes of love, like art, is to bring harmony and order out of chaos, to introduce meaning and affect where before there was none, to give rhythmic variations, highs and lows to a landscape that was previously flat. — Molly Haskell
You should know the proper terminology for the different parts of your stylesheet. Of all places, the Microsoft Web site gives us some invaluable assistance in learning the proper names of different CSS components. The page is old and hasn’t been updated in a long while, but the information itself is solid. Two more up-to-date references are Ian Lloyd’s Build Your Own Web Site The Right Way Using HTML & CSS, and Rachel Andrew’s The CSS Anthology: 101 Essential Tips, Tricks & Hacks.
CSS elements can be broken down by rule, selector, declaration, attribute, and value.
This is an entire rule (sometimes called a style declaration):
p { font-size: 10px; }
Or, if you prefer:
(Illustration used courtesy of David Heitmeyer.)
A selector is the HTML tag being styled:
p
The declaration (sometimes called a declaration block) is the portion of the CSS rule within the curly brackets:
{ font-size: 10px; }
Here’s a different illustration:
(Illustration used courtesy of David Heitmeyer.)
The attribute (sometimes called the property) is the particular element that is applied to a selector:
font-size
The value is the, well, value assigned to a particular attribute:
10px;
Another way to look at it:
(Illustration used courtesy of David Heitmeyer.)
Let’s say we have this hypothetical command inside your stylesheet:
body { font-size: 0.8em; color: #ff0000; }
Tizag.com writes:
“Property” [or “Attribute”] is the CSS element you wish to manipulate and “value” represents the value of the specified attribute. The selector name creates a direct relationship with the HTML tag you want to edit.
What does that mean? Well, in our example above, the body
tag (the selector
) is manipulated — modified — by two attributes
that change the font size and the color of everything in the body.
We use these terms in these pages. Sometimes I switch up “property” and “attribute,” so be prepared to see both.
Note: Some designers write their CSS code all on one line, like this:
body {font-size: 0.8em; color: #ff0000; }
There’s nothing wrong with this.
Note: Most browsers can’t handle attribute values more than 1,024 characters in length.
And don’t forget to enclose your attributes in double quotes, even though HTML 4.01 Strict doesn’t explicitly require it in some instances. A corollary of this is Jennifer Niederst Robbins’s cogent reminder:
Be careful not to leave out the closing quotation mark, or all the content from the opening quotation mark until the browser encounters a subsequent quotation mark will be interpreted as part of the value and won’t display in the browser. This is a simple mistake that can cause hours of frustration.
Selector Types
There are several types of selectors commonly in use.
Type Selectors
Basically, a “type selector” styles every instance of a particular HTML element appearing in the site. For instance:
a { color: #ff0000; }
has every single a
element (essentially, every link) in your site appearing in bright red. Andrew writes: “Type selectors are often used to set the basic styles that will appear throughout a web site.” Easy enough, though using type selectors paints with a relatively broad brush.
Class Selectors
As noted, type selectors style every instance of a particular element. Maybe you don’t want that. Let’s say you have a section of your page where you want your links (the a
elements) to appear in a stylish, muted gray instead of that firehouse red you’ve chosen for other parts of your site. Easy enough, you assign a class.
We create the following class in our stylesheet:
.subtlelink { color: #808080; }
Now, when we assign that class to a link in our HTML code:
<a href="http://www.yahoo.com" title="Yahoo" class="subtlelink">Yahoo</a>
those links, and only those links, will appear in a nice, subtle gray.
Note: Actually, they will only if you put the .subtlelink
below (after) the original red-styled links in your stylesheet. Specificity comes into play here. You’ll find out more about specificity later on this page.
ID Selectors
Those of us who know these things know that classes and IDs work much alike.
However, an ID can only appear once on a page, so they are usually used for one particular element on a page.
#navigation a { color: #808080; }
gives us those gray links only inside an HTML element designated as “navigation”:
<div class="navigation"> <p><a href="http://www.yahoo.com" title="Yahoo">Yahoo</a></p> </div>
We can combine ID and class selectors:
#navigation .subtlelink { color: #808080; }
like so:
<div id="navigation"> <p><a href="http://www.yahoo.com" title="Yahoo" class="subtlelink">Yahoo</a></p> </div>
Descendant Selectors
Basically, this means that if you include more than one element inside a styled class (such as our given “subtlelink”) or ID, everything gets styled.
In other words, this:
#navigation a { color: #808080; }
styles all of these links:
<div id="navigation"> <p><a href="http://www.yahoo.com" title="Yahoo">Yahoo</a></p> <p><a href="http://www.google.com" title="Google">Google</a></p> <p><a href="http://www.altavista.com" title="Alta Vista">Alta Vista</a></p> </div>
A descendant selector is made up of a list of selectors, separated by spaces (very important!) that matches a page element or group of elements from the outside in. In our example, our page contains a div
that has the ID of navigation
. As a result, #navigation a
refers to all of the a
elements inside the #navigation
div.
Confused yet? I wrote that (under the guidance of Andrew’s excellent book) and I’m confused! Trust me, this works.
Child Selectors
Lastly, we have child selectors, which refers to the concept of inheritance.
Andrew defines child selectors thusly: “The descendant selector matches all elements that are descendants of the parent element, including elements that are not direct descendants.”
Say what? Let’s look at an example, based on a tutorial by CSS guru Eric Meyer. You’re going to use the > (greater-than symbol) for this.
Let’s say we want to make the paragraph text in the body of our page green. We could write it thusly:
body > p { color: green; }
Any paragraph which is a direct child of the body
element will have green text. However, any paragraph which is a child of another element, say a div
or a table
cell, won’t be green. Using this kind of coding ensures that only specifically targeted paragraphs (or whatever element you choose) are styled.
Let’s see another example. Say we want to make the italicized text in our paragraphs red. If we do this:
em { color: red; }
all of our italicized text throughout our document is red, regardless of where it is. But we just want to “redden” the italicized text in the paragraphs.
Less experienced Web designers might use a class, like so:
.reditalics { color: red; } ... <p class="reditalics">That was a <em>huge</em> piece of cake!</p>
You could certainly do this. It would even validate. But using the child selector property is more efficient. Here’s what you’d do instead:
p > em { color: red; } ... <p>That was a <em>huge</em> piece of cake!</p>
Your stylesheet is that much less bloated, as is your HTML code. Nice all the way around.
Meyer gives us this much more complex example for your stylesheet:
body > div > div > p { color: lime; background: cyan; }
Only a paragraph which is the child of the body
element, and nested inside two div
elements (no more and no less) will have this rather ugly color combination applied to it.
Adjacent-Sibling Selector
There is also something called the adjacent-sibling selector which works something like this:
h1 + p { padding-left: 10px; }
Only the first paragraph after an h1
heading would have the padding applied.
Since Internet Explorer 6 doesn’t recognize the adjacent-sibling rule, many designers don’t use it. Eric Meyer and Chris Coyier give more information on it.
Grouping Selectors
Selectors can be grouped together, as long as you separate them with a comma and a space. Instead of:
h1 { font-family: Arial, sans-serif; color: #fff; } h2 { font-family: Arial, sans-serif; color: #fff; } h3 { font-family: Arial, sans-serif; color: #fff; }
it’s much cleaner and easier to maintain to do this:
h1, h2, h3 { font-family: Arial, sans-serif; color: #fff; }
You can also differentiate between your elements, setting different rules for specific elements after setting a rule for a group. In other words, you can do this:
h1, h2, h3 { font-family: Arial, sans-serif; color: #fff; } h1 { font-size: 1.5em; }
In this example, your h1
element will be displayed in Arial, in white (#fff
), and in a 1.5em size. Note: For this to work, the standalone h1
coding must be after the group coding.
Lloyd tells us:
You can think of the commas in CSS selectors (like the one above) as the word “or.”
Declarations can also be grouped. In some stylesheets, you will see something like the following:
h1 { font-weight: bold; } h1 { font-size: 10px; } h1 { line-height: 12px; } h1 { font-family: Georgia, serif; }
Incredibly long-winded. Just combine them, separating each selector with a semicolon:
h1 { font-weight: bold; font-size: 10px; line-height: 12px; font-family: Georgia, serif; }
Contextual Selectors
You can classify individual selectors according to their context — in other words, according to the element you wish them to style. Generally, they override the styling you’ve added to (for example) your body
element, or the browser’s own defaults.
Following Ian Lloyd’s lead, I think we can get a pretty good grasp of what this means.
Let’s say you want to create a class called “highlight.” You want it to show its text in italics, and in a different font from the rest of the text.
More about styling your fonts.
You’re only going to use it on certain paragraphs. So you create a contextual selector:
.highlight p { font-style: italic; font-family: Georgia, "Times New Roman", serif; }
By wrapping a paragraph, or a group of paragraphs, in a div
with the highlight
class, you can have those paragraphs appear in your styling:
<div class="highlight"> <p>This text is italicized and displays in Georgia.</p> </div>
More about the DIV and SPAN elements.
That will work great on the designated paragraphs, and other paragraphs will keep the original styling.
However, this will not work:
<p class="highlight">This text is supposed to appear in italics and Georgia, but it will not.</p>
Why not? Because your highlight p
CSS command already names a p
in its selector. By designating a paragraph (a second p
) as containing the class “highlight”, you give the browser one too many paragraphs to search for. Your “highlight”-styled paragraph won’t display properly.
Contextual selectors work with more than paragraphs. Let’s say you have a link inside your navigational scheme, which you have sensibly ID’d as “navigation.” By creating the following in your stylesheet:
#navigation a { text-decoration: none; color: #ff0000; }
you’ve ensured that all the links inside this scheme will have no underline, and will be red in color:
<div id="navigation"> <p><a href="links.html" title="Links">Links</a></p> <p><a href="contact.html" title="Contact Me">Contact Me</a></p> </div>
Let’s say you want to ensure that all the paragraphs in your footer (which you’ve ID’d as “footer”) have their lines spaced at 150% of the normal line spacing. By creating the following in your stylesheet:
#footer p { line-height: 150%; }
you ensure that everything in your footer is so spaced:
<div id="footer"> <p>Footer text.</p> </div>
while your other paragraphs enjoy the original spacing.
I cribbed those two examples directly from Lloyd’s book; he provides several more that serve to thoroughly illustrate the concept.
Pseudo-classes
I’ve already gone into some detail about pseudo-classes in another page of this site, as they pertain to styling links:
More about using pseudo-classes in link styling.
Most of the pseudo-classes you’ll see used pertain to styling links. There is one more I’m going to show you, however, because it has some usefulness all its own.
First-child
The first-child
selector works on an element that is the “first child” of a parent element. For example, if you have a <ul>
using the class childlist
, with first-child styling on that list’s <li>
, only the first list element will be styled. Like so:
.childlist li:first-child { { color: #cd3700; font-family: Georgia, "Times New Roman", serif; } ... <ul class="childlist"> <li>Some text.</li> <li>Some text.</li> </ul>
gives us:
- Some text.
- Some text.
Not bad. Unfortunately, this selector doesn’t work at all in IE 6, and doesn’t work right in later versions. Newer versions of Firefox, Opera, and Safari implement it properly, but older versions do not.
Pseudo-elements
You’ll see these in some more sophisticated stylesheets; they aren’t supported by all browsers (yes, that would be IE 6 and others), and not every designer relies on them. Having said all that, let’s take a quick peek at what they are and how they work.
My pals Tommy Olsson and Paul O’Brien write:
Pseudo-elements match virtual elements that don’t exist explicitly in the document tree. Pseudo-elements can be dynamic, inasmuch as the virtual elements they represent can change, for example, when the width of the browser window is altered. They can also represent content that’s generated by CSS rules.
To make it even more interesting, CSS1 and CSS2 have pseudo-elements start with a single colon: :
. But CSS3 pseudo-elements use a double colon: ::
, in order to differentiate them from pseudo-classes, which are discussed above.
Well, that explains it, let’s move on … no? Still confused? To tell you the truth, that explanation isn’t very clear to me, either (though it is absolutely accurate).
Basically, pseudo-elements add certain effects to chosen selectors. There are five of them:
- first-letter
- styles the first letter of a block of text
- first-line
- styles the first line of a block of text
- before
- specifies content to be inserted before a specific element
- after
- specifies content to be inserted after a specific element
- selection (CSS3)
- represents a part of the document highlighted by the user
Hmmm, not all of that is clear either. Let’s look at some examples:
First-letter
First-letter is, perhaps, the most popular of the five, because it’s so often used to create "drop cap" styling effects. It’s supported badly in IE 6 and 7, and in older versions of Firefox and Opera. Assuming you’re not running one of those browsers, you should be able to see the effect below.
Let’s say we have a paragraph that we want to style with a drop cap; we’ll set that paragraph apart with the class dropcap
. The code, both CSS and HTML, might look like this:
p.dropcap:first-letter { font-size: 300%; color: #cd3700; font-family: Georgia, "Times New Roman", serif; } ... <p class="dropcap">This paragraph is styled with a drop cap.</p>
Which gives us this:
This paragraph is styled with a drop cap.
It’s a nice effect, and one very familiar to print readers and designers.
First-line
You’ll see some magazine articles in which the entire first line is styled somewhat differently – small caps are popular, as are different spacings, typefaces, boldfacing, or other effects. A similar effect can be achieved using the first-line selector.
You might use the following CSS code:
p.firstline:first-line { font-variant: small-caps; font-family: Georgia, "Times New Roman", serif; } ... <p class="firstline">The first line of this paragraph gets some styling. But only the first. Check the second line out for the full effect. Nifty, huh?</p>
Which gives us this:
The first line of this paragraph gets some styling. But only the first. Check the second line out for the full effect. Nifty, huh?
It’s a very cool effect. Unfortunately, the only mainstream browsers to fully support this selector are IE 8, Safari, and Chrome. And this selector triggers some unusual specificity and inheritance behaviors. That’s why you don’t see it used very often. And why you may not be seeing it in your browser right now.
Before
The before selector adds “generated content” before a specified element, and styles that generated content.
Say what? Let’s try it out. Unfortunately, IE 6 and 7 don’t deal with the before selector at all, and IE 8 doesn’t handle it properly. Older versions of Firefox don’t handle it completely. Newer versions of Opera, and Safari and Chrome, do display the selected text properly.
Let’s say we want to insert some larger, orange text before the rest of the text in a designated paragraph:
More about character entities.
p.addtext:before { content: "Check me out!"; font-size: 24px; color: #cd3700; font-family: Georgia, "Times New Roman", serif; }
which, in the proper browsers, gives us:
This text has a large block of orange text before it.
This example may seem a bit pointless – you could just use a span
– but in some situations, say creating breadcrumb navigation, the selector becomes quite useful. At least it does in the browsers that support it.
After
You’ve probably already figured out that this selector is just like its sister, the before
selector, except it causes the text to come after the specified element, not before.
p.addtext2:after { content: "Check me out!"; font-size: 24px; color: #cd3700; font-family: Georgia, "Times New Roman", serif; }
which, in the proper browsers, gives us:
This text has a large block of orange text after it.
This one has similar browser issues as the other one.
Selector
I don’t use this one and you shouldn’t either, because no version of Internet Explorer or Firefox supports it. Neither do older versions of Opera, though Opera 9.5 and above does. Safari and Chrome support it. But a selector unsupported by both IE and Firefox … I don’t think so.
The SitePoint experts Tommy Olsson and Paul O’Brien give more information, if you’re interested.
Cascading Order
We’ve discussed the “style” aspect of CSS, but we have not mentioned the “cascading” aspect. Basically, this comes into play when one element is superseded by another in the stylesheet, or when two elements contradict one another. There must be some way for one element to “win out”. The simplest (and therefore the least accurate) way to view this is “last one in wins.” In other words, the last selector to be cited overrides earlier mentions.
Web designer Craig Grannell explains it a bit differently:
The value closest to the element in question is the one that is applied.
Well, that’s confusing. Let’s see an example. Let’s say you make your h2
green:
h2 { color: #008000; }
but farther down in your stylesheet, you forget what you did earlier, and again style your h2
, this time in stunning purple:
h2 { color: #800080; }
All of your h2
text will appear in purple. The purple, appearing later in the stylesheet, overrides the green.
A more complete list of "CSS overrides," or "cascades," can be found in the WDG HTML Help pages. I’ve simplified their list for you:
- !important. The
!important
attribute wins out over everything, and as a result is often misused. Use this powerful attribute wisely and with restraint. More about the!important
attribute can be found here. - Specificity. The “specificity” rule is quite confusing, and is explained more thoroughly here. Basically, the higher a rule’s specificity, the more “weight” it carries in the stylesheet, and will “win out” over a less “weighty” rule.
- Last rule specified wins. As described above. Both the
!important
attribute and “specificity” win out over “last one in wins.”
It’s also worth noting that when you import (or link) multiple stylesheets, say a print stylesheet, the cascade principle applies here, also. Anything in the second (or third, or fourth) stylesheet override the properties in the first.
Specificity
A concept related to the cascading order is specificity. The general rule of thumb is:
The more specific a selector is, the more weight it has.
Let’s take the following examples from a stylesheet:
strong { color: red; }
h1 strong { color: blue; }
Which one has more “weight” in your stylesheet? In the above examples, the first strong
rule will make sure that everything designated strong
in your document displays in red. However, any h1
elements also designated strong
will display in blue. Why? Because an element in a particular context is more specific, and has more weight, than the element alone.
So the second one is more specific. Got it? Not as easy to grasp as it might seem!
Let me make it even more complicated.
There are “levels” of specificity. Here they are, in order from least specific to most specific.
- Individual element and pseudoelement selectors (i.e.
p
or:link
) - Contextual selectors (i.e.
h1 strong
) - Class selectors (i.e.
p.special
) - ID selectors (i.e.
p#heading
)
So an ID selector has more weight than a class selector. And so forth.
(There is a method of calculating specificity; in fact, there are several variants of that method. It’s complicated and, frankly, you don’t need to know it at this stage. However, if you decide you need to know it, Roger Johannson and Vitaly Friedman can help you out.)
Don’t forget: a rule or selector marked !important
overrides specificity.
More about the “important” property.
Using Lower Case in CSS
It’s not a hard-and-fast rule that you should use all lower case letters in typing your CSS, but, well, you should. It’s best practices for a number of reasons, mostly consistency, and because if you ever find yourself writing XHTML, you’ll have to use lower case letters. So why not use it from the outset? Also, CSS classes and IDs are case-sensitive: in other words, this class:
.typeset
is different from this one:
.typeSet
You can imagine the confusion that could ensue once you start going down that road. Unless you can keep all of those upper- and lower-case class and IDs straight, just use lower case letters in all of your CSS. You’ll be glad you did.