The KIRUPA orange logo! A stylized orange made to look like a glass of orange juice!

FORUM

CSS Selectors: Type, Class, and ID

by kirupa   |   filed under HTML and CSS

By now, you probably know that you use CSS styles to alter the look of your HTML document. The way CSS bobs and weaves through your document to style the right elements is both fascinating as well as useful for you to understand if you want to create great looking applications and web sites.

In this tutorial, you will learn how common CSS selectors work to map a particular rule to elements in your document. We will start off by deconstructing and understanding very simple examples and then moving to more complicated examples that you will encounter...in the wild!

Note

If any of the CSS terminology such as selectors and rules is unfamiliar to you, check out the Anatomy of a CSS Style 101 article for a quick introduction.

A Simple Type Selector

Let's first start by looking at a simple style rule whose selector applies to all p tags:

p {
	font-family: Cambria, serif;
	font-size: xx-large;
}

With what we have here, if any p tags are encountered in our HTML document, this rule will get applied. For example, the following text will fall under the influence of this rule:

<p>Do or do not...there is no try.</p>

This doesn't seem too crazy, right? Because our browser sees a match between the p selector in the style rule and the p tag in your document, it applies this style to that element. This type of a selector is known as a type selector because it applies to elements whose types match what it specifies.

Let's say our document had many p tags with some p tags nested inside other elements:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Selectors</title>
</head>

<body>
  <p>Do or do not...there is no try.</p>

  <div id="mainHeading">
    <p>Coming Soon in 2011</p>
    <p>( to a theater near you )</p>
  </div>

  <table>
    <tr>
      <td>
        <p>column1</p>
      </td>
      <td>
        <p>column2</p>
      </td>
    </tr>
    <tr>
      <td>
        <p>data1</p>
      </td>
      <td>
        <p>data2</p>
      </td>
    </tr>
  </table>
</body>

</html>

The rule we defined earlier will apply to every instance of the p tag in the document. The reason is because the selector isn't very specific on which types of p tags to apply the rule to. To describe this situation more formally, this particular selector is said to lack specificity. It will apply to every p tag without any fuss. Sometimes that is the behavior we want. Most of the time, we will want a bit more control, and the following sections will explain the approaches we have for giving us greater control over how our styles get applied.

Targeting by Name: Class and ID Selectors

So far, we've only seen a simple type selector that applies its styles to all occurrences of the p tag. While type selectors that only apply to a particular type of element is useful, for many types of visual changes you want to make, you want to use selectors that can be applied broadly to different types of elements. To help us accomplish this, we have class selectors and id selectors. Let's look at them now.

Class Selector

Instead of targeting the elements to style by their type, what if we had a way to specifically target each element we wish to style by name? This is where the class selector comes in. Let's say this is our HTML:

<div> 
  <p>Coming Soon in 2011</p> 
  <p>( to a theater near you )</p> 
</div>

What we want to do is apply a blue background color to the second p element only. The first thing we'll do is distinguish our second p element by giving it a name. The way we will give it a name is by setting a class attribute on it with a value of cool:

<div> 
  <p>Coming Soon in 2011</p> 
  <p class="cool">( to a theater near you )</p> 
</div>

If we wish to style our cool element, we can specify a class selector that targets this element directly:

.cool {
  background-color: #AADCFF;
}

This selector isn't named after an HTML element, but instead it is named after the cool class value we defined in our HTML earlier. When it comes to class-based selectors, we must specify a period in front of the selector name. That period is an important detail to have in our CSS, but do note that this period is not a part of what we specify in the class attribute in our HTML.

Another detail of targeting styles via the class attribute is that we can have multiple elements with the same class value:

<ul> 
  <li class="cool">Uno</li>
  <li class="cool">Dos</li>
  <li>Tres</li>
  <li>Catorce</li>
</ul>

Our .cool style selector will apply to both of the first two list elements in our snippet here, but it will not apply to the last two list elements.

ID Selector

Another way to style an element by name is by using an ID selector where the element we wish to style has an id attribute set to a single value:

<div id="spaceship"> 
  <p>Do or do not...there is no try.</p> 
</div>

In the above snippet, we have a div element that has the id attribute set to spaceship. If we want to apply a style to just this particular element we can use an ID selector that looks as follows:

#spaceship {  
  background-color: #E6F8FF;
}

Notice that the selector's value is #spaceship. The hashtag (#) is important because it designates the selector as an ID based selector, and the value that follows it specifies the ID of the element we wish to apply this rule to.

Lastly, we saw earlier how we can have multiple elements with the same class value. That doesn't fly with id values. The rule is that id values need to be unique and only one element on the page can have a particular id.

Nested Selectors

Our selectors do not have to consist of single HTML types, class names, or ID values. We can string together combinations of selectors to constrain the range of elements we can apply a style rule to.

Let's look at an example where your HTML looks as follows:

<body>
<p>Do or do not...there is no try.</p>
  
<div id="mainHeading">
 <p>Coming Soon in 2011</p>
 <p>( to a theater near you )</p>
</div>
  
</body>

What we want to do is only apply some styles to the p tags (highlighted in green) that are descendants of the mainHeading div tag. The p tag that is outside of the mainHeading div tag (highlighted in orange) should remain unaffected.

The rule we had towards the beginning of this article will not work:

<style>
p {
font-family: Cambria, serif;
font-size: xx-large;
}
</style>

Like you saw earlier, the selector for this rule doesn't discriminate - it just applies the rule to any and all p tags it encounters in the document. To constrain the elements your selector applies to, you can nest additional selectors to an existing selector.

Because the p tags we want to affect live inside a div tag, we can modify our selector as such:

<style>
div p {
font-family: Cambria, serif;
font-size: xx-large;
}
</style>

Notice that our selector now specifies that this rule applies anywhere in your document only when a p tag is a descendant of a div tag. Any ordinary p tags will no longer get to bask in the awesomeness this rule provides.

One thing to keep in mind about nested selectors is that, just because your selector says div p, it does not mean that this rule applies only to an element p that is a direct child of the div. Your div can have many levels of of children under it before a p element is encountered, but as long as p falls under the path of the div (aka a descendant), you are all good.

Below is an example of this:

<div id="mainHeading">
<p>Coming Soon in 2011</p>
  <ul>
    <li>
      <p>( to a theater near you )</p>
    </li>
  </ul>
</div>

Notice in this example that the second p element is actually under a list item inside an unordered list. Despite its distance from the div element, because this p tag is still a descendant, the style rule still applies.

Let's go a bit further. Let's say that constraining your styles to p tags that are descendants of a div element is still too freewheeling. Instead, you want to apply your style to p tags that are descendants of the div whose ID is mainHeading.

In this case, taking the same HTML snippet you saw a few seconds ago, you don't have to do anything too different to what your selector looks like. Instead of your selector being div p, you simply use #mainHeading p instead:

<style>
#mainHeading p {
font-family: Cambria, serif;
font-size: xx-large;
}
</style>

You can mix and match selector types to help pinpoint the range of elements you want to affect! Think of matching all of the CSS rules to elements in your document as nothing more than a giant game of pattern matching!

Nested Selectors (...again!)

This section is entirely optional, but because nesting selectors and pattern matching takes some getting used to, let's look at another example to help bake it all in.

In this example, your document looks as follows:

<div id="mainParent">
  <p>I'm just here to throw you off!</p>
  <div id="container" class="awesome">
    <div id="spaceship">
      <p class="awesome">Do or do not...there is no try.</p>
    </div>
  </div>
</div>

You have three nested divs, and at the very bottom of those divs is a p tag containing some text. As you can guess, we want to style only this p tag, and we must only do this through CSS. In other words, you can't modify your HTML and give your p tag a unique ID and take care of it easily with a single ID selector. There are several ways of accomplishing this, and we'll explore a few of those ways.

Nested Type Selectors

Using just type selectors, one approach may be to do the following:

<style>
div div p {
font-family: Cambria, serif;
font-size: xx-large;
}
</style>

The only p tags that will be accepted are ones that are desecendants of at least two divs. This eliminates the first p tag because it is the descendant of only a single div, but the p tag we are interested in gets hit. The reason is that our p tag with the class name awesome is the descendant of three div elements!

Nested ID and Type Selectors

Another approach you can take can be:

<style>
#spaceship p {
font-family: Cambria, serif;
font-size: xx-large;
}
</style>

This rule will apply to any p tags that are a descendant of an element whose ID is spaceship. This means our p tag will be affected by this style because it is a direct child of a div whose ID is spaceship.

Nested ID and Class Selectors

The last example we will see is one where you combine both the ID and class-based selector into your rule:

<style>
#spaceship .awesome {
font-family: Cambria, serif;
font-size: xx-large;
}
</style>

In this case, any element whose class value is awesome that is also a descendant of an element whose ID value is spaceship will fall under the umbrella of this rule.

We won't look at any more examples, but what you have seen so far should give you a good taste of how to specifically pinpoint an element or a set of elements for applying a style to. As long as you have a good visualization of the DOM / hierarchy of the elements you wish to style, constructing an appropriate selector with the right specificity will become very easy after a few tries!

Conclusion

Well, that's all there is to understanding how to use type, class, and ID selectors. Armed with these three weapons, you can take on pretty much any army of HTML-based orcs and trolls as you fight your way through Lordaeron. Yes, I need a vacation.

Got a question or just want to chat? Comment below or drop by our forums (they are actually the same thing!) where a bunch of the friendliest people you'll ever run into will be happy to help you out!

When Kirupa isn’t busy writing about himself in 3rd person, he is practicing social distancing…even on his Twitter, Facebook, and LinkedIn profiles.

Hit Subscribe to get cool tips, tricks, selfies, and more personally hand-delivered to your inbox.

COMMENTS

Serving you freshly baked content since 1998!
Killer hosting by (mt) mediatemple

Twitter Youtube Facebook Pinterest Instagram Github