Understanding Selectors in CSS

Chapter 7

The example of the menu, and the two pseudo-selectors will allow us to learn one more important concept. You may have noticed that each selector our CSS code consists of the same names as their respective HTML tags. So, whenever we change something in the structure of code we must also change the CSS. For example, sometimes it might be necessary to no longer have a heading:

<h1>Justin Beaver shaved his mustache</h1>

Let's instead use the element <p>:

<p>Justin Beaver shaved his mustache</p>

With this change, we run the risk of errors in the display. To minimize this risk, we use CSS classes and IDs.

Every HTML element may have a special attribute named "class," where we can provide one or more class names. Here are a few examples of how you can add this attribute:

And so on. Note that class names are arbitrary, and must be single words or "clusters" using dashes like in the example of "my-item" or underscores like "special_item".

You can also add multiple class names for a single tag:

You might be wondering what this means and why classes are useful. Suppose that we create a page with information on sports news. Let us assume that we have a list of news and we want to highlight one item (I've highlighted one line of our list below). The code would look something like this:

<article><p>normal news</p></article>
<article><p>special news</p></article>
<article><p>normal news</p></article>
<article><p>normal news</p></article>
<article><p>normal news</p></article>

If we wanted to write CSS code that distinguishes a special background for only the features news, we have a problem. Our expertise so far allows us to "style" all the elements in <article> in the form of the selector:

article {}

But this will look for all <article> elements. CSS classes allow us to avoid this confusion. Let's describe each of the <article> elements with a class that corresponds to its importance for the entire site. So, let's call the important news "main-news" and the rest "normal-news" as shown in the HTML code below:

<article class="normal-news"><p>normal news</p></article>
<article class="main-news"><p>special news</p></article>
<article class="normal-news"><p>normal news</p></article>
<article class="normal-news"><p>normal news</p></article>
<article class="normal-news"><p>normal news</p></article>

Now, using CSS, we can use the following selectors:

.main-news {
  background-color: LightBlue;
}

.normal-news {
  background-color: LightYellow;
}

For each class, note that they begin with a dot "." followed by the class name. So we can use this construction to target selector elements of the same class in HTML. The "main news" will now have a background color of light blue, while a normal news is coloured in LightYellow.

In the browser, this code looks something like this:

Thanks to CSS classes, we can denote characteristics for specific elements on the page, that allows us to simultaneously target and ignore elements with the same tags. If we ever wanted to change <article> tag to something else, let's say <p>, we wouldn't need to modify our CSS code as well. That's a huge benefit.

The essence of classes is explained in the following diagram:

In addition to classes, we also have identifiers. We use the attribute called "id" and give it a value, very similar to how classes work. An example of an ID in HTML might look like this:

<p id="main-content"></p>

The CSS code for identifiers looks something like this:

#main-content {
  background-color: red;
}

Instead of a "." before the element, we use a hashtag "#" for identifiers, followed by the element name. The code above specifies that elements with the ID "main-content" should have a red background.

It's very important to remember that identifiers are unique, so the identifier can only be used once in an HTML document. The use of the attribute "id" should be preceded by careful planning and analysis. It's also good practice to not abuse "id" usage, as it is rare that good sites consists of several unique elements.

The operation of identifiers is summarized in the following diagram:

With our new knowledge of classes and identifiers, let's rewrite our menu code to make it more robust against changes in the HTML file. Perhaps in the future we decide that we would like to make it using other tags than <ul> and <li>. If we use the appropriate classes, then we can sleep peacefully without having to worry about changing the CSS code in parallel.

Let's start by modifying our HTML. Currently, our code for the navigation menu currently looks like this:

<nav>
  <ul>
    <li>
      <a href="index.html">Home</a>
    </li>
    <li>
      <a href="training.html">Training</a>
    </li>
    <li>
      <a href="conferences.html">Conferences</a>
    </li>
    <li>
      <a href="about.html">About us</a>
    </li>
  </ul>
</nav>

Let's introduce a class. We'll give the entire container of the menu (tag <ul>) a class, and each item under it (tag <li>) a "child" class.

<nav>
  <ul class="site-nav">
    <li class="site-nav-item">
      <a href="index.html">Home</a>
    </li>
    <li class="site-nav-item">
      <a href="training.html">Training</a>
    </li>
    <li class="site-nav-item">
      <a href="conferences.html">Conferences</a>
    </li>
    <li class="site-nav-item">
      <a href="about.html">About us</a>
    </li>
  </ul>
</nav>

For this menu, I've given the unordered list <ul> the "site-nav" class, while each <li> item has the class "site-nav-item."

Time to customize the CSS code:

.site-nav {
  background-color: PaleVioletRed;
  list-style: none;
  padding: 0;
  width: 200px;
  border: 1px solid MediumVioletRed;
}

.site-nav .site-nav-item {
  border-bottom: 1px solid MediumVioletRed;
  padding: 5px;
}

.site-nav .site-nav-item:last-child {
  border-bottom: 0;
}

.site-nav .site-nav-item a {
  color: white;
  text-decoration: none;
}

.site-nav .site-nav-item a:hover {
  text-decoration: underline;
}

To better understand what has changed, look at the comparison of the old and new CSS code:

Try to compare each selector. As you can see, we traded the tag names for class names, which gives us much more flexibility in writing code. Note that they are shortened by removing the redundant "nav" tag.

It's important to try to use class names as selectors instead of tags, unless it is obvious like <a> for addresses. This cannot be replaced with any other HTML tag. Identifiers are only used when the item is unique in the page. In this cause, it could be just the menu, but oftentimes navigation appears several times on a website (for example at the bottom and top).

The operation and definition of classes and IDs are summarized in the following diagram: