CSS Selectors

So far, we have only been able to select every instance of a particular tag in our stylesheets. This is often very useful, but limiting. There are many more ways to select content for modification in CSS, and we should explore some.

Classes

There are often cases where we use one element for different purposes on a page. We have already seen the class attribute used to distinguish different uses.

For example, suppose we are creating a web page for a recipe. We might come up with markup that uses several different lists, but with different roles.

<h2>Ingredients</h2>
<ul class="ingredients">
<li>2 cups milk</li><li>3 oz flour</li>…
</ul>

<h2>Method</h2>
<ol><li>Combine.</li><li>Stir.</li>…</ol>

<h2>Common Problems</h2>
<ul class="problems">
<li>If it didn't rise, you can …</li>
<li>Sometimes if your milk is too …</li>
</ul>

Here we have two <ul> elements. Order of the items doesn't matter in either case, so <ul> is the right tag to use, but it would be totally reasonable to want these to look different on the page. We thus used class to indicate their specific role.

The class property won't change the page in any way by itself, but we can now uses these classes to grab particular elements in CSS:

ul {
  list-style-type: disc;  
}
ul.problems {
  font-size: smaller;
}

The second selector here (“ul.problems”) is a class selector. It selects all <ul> elements that have class="problems" but does not change other unordered lists. The first selector (“ul”) still selects all <ul> elements, whether they have a class or not.

Classes can be added as you find you need them to make the appearance of the page match your intent. For example, while creating a recipe page as above, you might find that you have some ingredients that are optional (e.g. you can add hot sauce if you like it).

In a case like that, you can go back and add class="optional" to elements where it's relevant:

<ul class="ingredients">
  <li>…</li>
  <li>…</li>
  <li class="optional">…</li>
</ul>

Then you can return to your stylesheet and change the appearance of just those elements:

.optional {
  color: gray;
  font-style: italic;
}

The selector .optional selects any elements with class="optional", not just <li class="optional">. In our example, it would do the same thing as li.optional since we only have <li> elements with that class, but this way we could add other “optional” content ( like <p class="optional">) and have it styled the same way.

IDs

We have also seen the id property: an id value can occur only once on a page. So, we use id to uniquely identify things.

For example, we know we will only have one page footer (information at the bottom of the page about the site, etc.). There is a tag <footer>, but we might have something like copyright information inside it that we want to style separately: we know there will only be one copyright statement on a particular page, so we use id:

Then we can select just the paragraph with that identifier like this:

p#copyright {
  font-weight: bold;
  color: red;
}

Above, we used class="ingredients" instead of id="ingredients" because we could create a page with multiple recipes, so multiple lists of ingredients. Here we know the copyright info will occur only once so we can use id="copyright".

Since id values are unique, they can also be used to identify a part of the page (thus the name). We will use this in the unit on JavaScript and beyond, but for now, it can be used to link to a particular position on a page. For example, this topic starts with an element that has an id specified. We can link to that part (id="identifiers") of the page (css-selectors.html) in HTML like this:

That will create a link to the start of the section about IDs (like that).

Contextual Selectors

It is often useful to select elements based on where they are on the page. For example, you might want to modify emphasized text that is in headings (but not elsewhere), or only list items in ordered lists (but not unordered).

For example, suppose we want to space out the elements of lists, inserting whitespace between each item. If we want to modify all <li>s (inside both <ol> and <ul> elements), we can do it like this:

li {
  margin-top: 1em;
}

But if we only want to modify <ol> lists (leaving <ul> alone), we need to select only the list items inside ordered lists. To do this, we can use contextual selectors that find one element inside another.

ol li {
  margin-top: 1em;
}

The selector “ol li” will select any <li> that is inside an <ol> element but not other list items.

For another use of contextual selectors, you might find that you don't like the default appearance of links within headings: the blue colour is distyracting and you want the links to only be underlined.

Page with a link in a heading
Page with a link in a heading

This CSS with a contextual selector can be used to modify only the links in level-2 headings:

h2 a {
  color: black;
}

The page will then look like this. (The link in the heading has turned black, in case you can't see it because of the device you're viewing this on.)

Restyled link in a heading
Restyled link in a heading

Other Selectors

There are other selectors that can be used in CSS that we won't cover in detail here, but here is a quick indication of some of the things you can select if you need to:

Pseudo-class selectors
There are some special properties of elements that the browser can automatically detect and apply styles. Probably the most useful are the link pseudo-classes: links that have not been visited (usually blue), visited (usually purple), and currently-being-clicked (usually red). Here is CSS to set colours similar to the defaults:
a:link {
  color: blue;
}
a:visited {
  color: purple;
}
a:active {
  color: red;
}
Child selectors
The contextual selector (space) will select an element that's anywhere inside the element. For example, if you have a <ol> with a <ul> inside it, selecting with ol li will select the items of the <ol> as well, since they are somewhere inside the <ol>. That might not be what you intend.

This CSS will separately change the appearance of list items that are immediately within <ol>s and <ul>s:

ol>li {
  list-style-type: decimal;
}
ul>li {
  list-style-type: circle;
}

Combining Selectors

These selectors can be combined in any way you like. For example, here are selectors that would affect the appearance of (1) list items in the <ul class="ingredients">; (2) optional items in the ingredients list; (3) unvisited links with class="external":

ul.ingredients li {…}
ul.ingredients li.optional {…}
a:link.external {…}