Linux Professional Institute Learning Logo.
Skip to main content
  • Home
    • All Resources
    • LPI Learning Materials
    • Become a Contributor
    • Publishing Partners
    • Become a Publishing Partner
    • About
    • FAQ
    • Contributors
    • Roadmap
    • Contact
  • LPI.org
033.2 Lesson 1
Topic 031: Software Development and Web Technologies
031.1 Software Development Basic
  • 031.1 Lesson 1
031.2 Web Application Architecture
  • 031.2 Lesson 1
031.3 HTTP Basics
  • 031.3 Lesson 1
Topic 032: HTML Document Markup
032.1 HTML Document Anatomy
  • 032.1 Lesson 1
032.2 HTML Semantics and Document Hierarchy
  • 032.2 Lesson 1
032.3 HTML References and Embedded Resources
  • 032.3 Lesson 1
032.4 HTML Forms
  • 032.4 Lesson 1
Topic 033: CSS Content Styling
033.1 CSS Basics
  • 033.1 Lesson 1
033.2 CSS Selectors and Style Application
  • 033.2 Lesson 1
033.3 CSS Styling
  • 033.3 Lesson 1
033.4 CSS Box Model and Layout
  • 033.4 Lesson 1
Topic 034: JavaScript Programming
034.1 JavaScript Execution and Syntax
  • 034.1 Lesson 1
034.2 JavaScript Data Structures
  • 034.2 Lesson 1
034.3 JavaScript Control Structures and Functions
  • 034.3 Lesson 1
  • 034.3 Lesson 2
034.4 JavaScript Manipulation of Website Content and Styling
  • 034.4 Lesson 1
Topic 035: NodeJS Server Programming
035.1 NodeJS Basics
  • 035.1 Lesson 1
035.2 NodeJS Express Basics
  • 035.2 Lesson 1
  • 035.2 Lesson 2
035.3 SQL Basics
  • 035.3 Lesson 1
How to get certified
  1. Topic 033: CSS Content Styling
  2. 033.2 CSS Selectors and Style Application
  3. 033.2 Lesson 1

033.2 Lesson 1

Certificate:

Web Development Essentials

Version:

1.0

Topic:

033 CSS Content Styling

Objective:

033.2 CSS Selectors and Style Application

Lesson:

1 of 1

Introduction

When writing a CSS rule, we must tell the browser to which elements the rule applies. We do so by specifying a selector: a pattern that can match an element or group of elements. Selectors come in many different forms, which can be based on the element’s name, its attributes, its relative placement in the document structure, or a combination of these characteristics.

Page-Wide Styles

One of the advantages of using CSS is that you do not need to write individual rules to elements sharing the same style. An asterisk applies the rule to all elements in the web page, as shown in the following example:

* {
  color: purple;
  font-size: large;
}

The * selector is not the only method to apply a style rule to all elements in the page. A selector that simply matches an element by its tag name is called a type selector, so any HTML tag name such as body, p, table, em, etc., can be used as selectors. In CSS, the parent’s style is inherited by its children elements. So, in practice, using the * selector has the same effect as applying a rule to the body element:

body {
  color: purple;
  font-size: large;
}

Furthermore, the cascading feature of CSS allows you to fine tune the inherited properties of an element. You can write a general CSS rule that applies to all elements in the page, and then write rules for specific elements or sets of elements.

If the same element matches two or more conflicting rules, the browser applies the rule from the most specific selector. Take the following CSS rules as an example:

body {
  color: purple;
  font-size: large;
}

li {
  font-size: small;
}

The browser will apply the color: purple and font-size: large styles to all elements inside the body element. However, if there are li elements in the page, the browser will replace the font-size: large style by the font-size: small style, because the li selector has a stronger relationship with the li element than the body selector does.

CSS does not limit the number of equivalent selectors in the same stylesheet, so you can have two or more rules using the same selector:

li {
  font-size: small;
}

li {
  font-size: x-small;
}

In this case, both rules are equally specific to the li element. The browser cannot apply conflicting rules, so it will choose the rule that comes later in the CSS file. To avoid confusion, the recommendation is to group together all properties that use the same selector.

The order in which the rules appear in the stylesheet affect how they are applied in the document, but you can override this behavior by using an important rule. If, for any reason, you want to keep the two separate li rules, but force the application of the first one instead of the second one, mark the first rule as important:

li {
  font-size: small !important;
}

li {
  font-size: x-small;
}

Rules marked with !important should be used with caution, because they break the natural stylesheet cascading and make it harder to find and correct problems within the CSS file.

Restrictive Selectors

We saw that we can change certain inherited properties by using selectors matching specific tags. However, we usually need to use distinct styles for elements of the same type.

Attributes of HTML tags can be incorporated into selectors to restrict the set of elements they refer to. Suppose the HTML page you are working on has two types of unordered lists (<ul>): one is used at the top of the page as a menu to the sections of the website and the other type is used for conventional lists in the text body:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>CSS Basics</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>

<ul>
  <li><a href="/">Home</a></li>
  <li><a href="/articles">Articles</a></li>
  <li><a href="/about">About</a></li>
</ul>

<div id="content">

<p>The three rocky planets of the solar system are:</p>

<ul>
  <li>Mercury</li>
  <li>Venus</li>
  <li>Earth</li>
  <li>Mars</li>
</ul>

<p>The outer giant planets made most of gas are:</p>

<ul>
  <li>Jupiter</li>
  <li>Saturn</li>
  <li>Uranus</li>
  <li>Neptune</li>
</ul>

</div><!-- #content -->


<div id="footer">

<ul>
  <li><a href="/">Home</a></li>
  <li><a href="/articles">Articles</a></li>
  <li><a href="/about">About</a></li>
</ul>

</div><!-- #footer -->

</body>
</html>

By default, each list item has a black circle to its left. You may want to remove the circles from the top menu list while leaving the circles in the other list. However, you cannot simply use the li selector because doing so will also remove the circles in the list inside the text body section. You will need a way to tell the browser to modify only the list items used in one list, but not the other.

There are several ways to write selectors matching specific elements in the page. As mentioned earlier, we will first see how to use the elements' attributes to do so. For this example in particular, we can use the id attribute to specify the top list only.

The id attribute assigns a unique identifier to the corresponding element, which we can use as the selector part of the CSS rule. Before writing the CSS rule, edit the sample HTML file and add id="topmenu" to the ul element used for the top menu:

<ul id="topmenu">
  <li>Home</li>
  <li>Articles</li>
  <li>About</li>
</ul>

There is already a link element in the head section of the HTML document pointing to the style.css stylesheet file in the same folder, so we can add the following CSS rules to it:

ul#topmenu {
  list-style-type: none
}

The hash character is used in a selector, following an element, to designate an ID (without spaces separating them). The tag name to the left of the hash is optional, as there will be no other element with the same ID. Therefore, the selector could be written just as #topmenu.

Even though the list-style-type property is not a direct property of the ul element, CSS properties of the parent element are inherited by its children, so the style assigned to the ul element will be inherited by its child li elements.

Not all elements have an ID by which they can be selected. Indeed, only a few key layout elements in a page are expected to have IDs. Take the lists of planets used in the sample code, for instance. Although it is possible to assign unique IDs for each individual repeated element like these, this method is not practical for longer pages with lots of contents. Rather, we can use the parent div element’s ID as the selector to change the properties of its inner elements.

However, the div element is not directly related to HTML lists, so adding the list-style-type property to it will have no effect on its children. Thus, to change the black circle in the lists inside the content div to a hollow circle, we should use a descendant selector:

#topmenu {
  list-style-type: none
}

#content ul {
  list-style-type: circle
}

The #content ul selector is called a descendant selector because it matches only the ul elements that are children of the element whose ID is content. We can use as many levels of descendance as necessary. For instance, using #content ul li would match only the li elements that are descendants of ul elements that are descendants of the element whose ID is content. But in this example, the longer selector will have the same effect as using #content ul, because the li elements inherit the CSS properties set to their parent ul. Descendant selectors are an essential technique as the page layout grows in complexity.

Let’s say that now you want to change the font-style property of the list items in the topmenu list and in the list in the footer div to make them look oblique. You can’t simply write a CSS rule using ul as the selector, because it will also change the list items in the content div. So far, we have changed CSS properties using one selector at a time, and this method can also be used for this task:

#topmenu {
  font-style: oblique
}

#footer ul {
  font-style: oblique
}

Separate selectors are not the only way to do it, though. CSS allow us to group together selectors that share one or more styles, using a list of selectors separated by commas:

#topmenu, #footer ul {
  font-style: oblique
}

Grouping selectors eliminates the extra work of writing duplicate styles. Furthermore, you may want to change the property again in the future and may not remember to change it in all the different places.

Classes

If you do not want to worry too much about the element hierarchy, you can simply add a class to the set of elements you want to customize. Classes are similar to IDs, but instead of identifying only a single element in the page, they can identify a group of elements sharing the same characteristics.

Take the sample HTML page we are working on, for instance. It’s unlikely that in real-world pages we will find structures simple as that, so it would be more practical to select an element using classes only, or a combination of classes and descendancy. To apply the font-style: oblique property to the menu lists using classes, first we need to add the class property to the elements in the HTML file. We’ll do it first in the top menu:

<ul id="topmenu" class="menu">
  <li><a href="/">Home</a></li>
  <li><a href="/articles">Articles</a></li>
  <li><a href="/about">About</a></li>
</ul>

And then in the footer’s menu:

<div id="footer">

<ul class="menu">
  <li><a href="/">Home</a></li>
  <li><a href="/articles">Articles</a></li>
  <li><a href="/about">About</a></li>
</ul>

</div><!-- #footer -->

With that, we can replace the selector group #topmenu, #footer ul by the class-based selector .menu:

.menu {
  font-style: oblique
}

As with the ID-based selectors, adding the tag name to the left of the dot in class-based selectors is optional. However, unlike IDs, the same class is supposed to be used in more than one element and they do not even need to be of the same type. Therefore, if the menu class is shared among different element types, using the ul.menu selector would match only the ul elements having the menu class. Instead, using .menu as the selector will match any element having the menu class, regardless of its type.

Furthermore, elements can be associated to more than one class. We could differentiate between the top and the bottom menu by adding an extra class to each one of them:

<ul id="topmenu" class="menu top">

And in the footer’s menu:

<ul class="menu footer">

When the class attribute has more than one class, they must be separated by spaces. Now, in addition to the CSS rule shared between elements of the menu class, we can address the top and footer menu using their corresponding classes:

.menu {
  font-style: oblique
}

.menu.top {
  font-size: large
}

.menu.footer {
  font-size: small
}

Be aware that writing .menu.top differs from .menu .top (with a space between the words). The first selector will match elements that have both menu and top classes, whereas the second will match elements that have the top class and a parent element with the menu class.

Special Selectors

CSS selectors can also match dynamic states of elements. These selectors are particularly useful for interactive elements, such as hyperlinks. You may want the appearance of hyperlinks when the mouse pointer moves over them, to draw the visitor’s attention.

Back to our sample page, we could remove the underlines from the links in the top menu and show a line only when the mouse pointer moves over the corresponding link. To do this, we first write a rule to remove the underline from the links in the top menu:

.menu.top a {
  text-decoration: none
}

Then we use the :hover pseudo-class on those same elements to create a CSS rule that will apply only when the mouse pointer is over the corresponding element:

.menu.top a:hover {
  text-decoration: underline
}

The :hover pseudo-class selector accepts all the CSS properties of conventional CSS rules. Other pseudo-classes include :visited, which matches hyperlinks that have already been visited, and :focus, which matches form elements that have received focus.

Guided Exercises

  1. Suppose an HTML page has a stylesheet associated to it, containing the two following rules:

    p {
      color: green;
    }
    
    p {
      color: red;
    }

    What color will the browser apply to the text inside the p elements?

  2. What is the difference between using the ID selector div#main and #main?

  3. Which selector matches all p elements used inside a div with ID attribute #main?

  4. What is the difference between using the class selector p.highlight and .highlight?

Explorational Exercises

  1. Write a single CSS rule that changes the font-style property to oblique. The rule must match only a elements that are inside <div id="sidebar"></div> or <ul class="links"></ul>.

  2. Suppose you want to change the style of the elements whose class attribute is set to article reference, as in <p class="article reference">. However, the .article .reference selector does not appear to alter their appearance. Why is the selector not matching the elements as expected?

  3. Write a CSS rule to change the color property of all visited links in the page to red.

Summary

This lesson covers how to use CSS selectors and how the browser decides what styles to apply to each element. Being separate from the HTML markup, CSS provides many selectors to match individual elements or groups of elements in the page. The lesson goes through the following concepts and procedures:

  • Page wide styles and style inheritance.

  • Styling elements by type.

  • Using the element ID and class as the selector.

  • Compound selectors.

  • Using pseudo-classes to style elements dynamically.

Answers to Guided Exercises

  1. Suppose an HTML page has a stylesheet associated to it, containing the two following rules:

    p {
      color: green;
    }
    
    p {
      color: red;
    }

    What color will the browser apply to the text inside the p elements?

    The color red. When two or more equivalent selectors have conflicting properties, the browser will choose the last one.

  2. What is the difference between using the ID selector div#main and #main?

    The selector div#main matches a div element having the ID main, whereas the #main selector matches the element having the ID main, regardless of its type.

  3. Which selector matches all p elements used inside a div with ID attribute #main?

    The selector #main p or div#main p.

  4. What is the difference between using the class selector p.highlight and .highlight?

    The selector p.highlight matches only the elements of type p having the class highlight, whereas the .highlight selector matches all elements having the class highlight, regardless of their type.

Answers to Explorational Exercises

  1. Write a single CSS rule that changes the font-style property to oblique. The rule must match only a elements that are inside <div id="sidebar"></div> or <ul class="links"></ul>.

    #sidebar a, ul.links a {
      font-style: oblique
    }
  2. Suppose you want to change the style of the elements whose class attribute is set to article reference, as in <p class="article reference">. However, the .article .reference selector does not appear to alter their appearance. Why is the selector not matching the elements as expected?

    The .article .reference selector will match the elements having the class reference that are descendants of elements having the class article. To match elements having both article and reference classes, the selector should be .article.reference (without the space between them).

  3. Write a CSS rule to change the color property of all visited links in the page to red.

    a:visited {
      color: red;
    }

Linux Professional Insitute Inc. All rights reserved. Visit the Learning Materials website: https://learning.lpi.org
This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.

Next Lesson

033.3 CSS Styling (033.3 Lesson 1)

Read next lesson

Linux Professional Insitute Inc. All rights reserved. Visit the Learning Materials website: https://learning.lpi.org
This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.

LPI is a non-profit organization.

© 2023 Linux Professional Institute (LPI) is the global certification standard and career support organization for open source professionals. With more than 200,000 certification holders, it's the world’s first and largest vendor-neutral Linux and open source certification body. LPI has certified professionals in over 180 countries, delivers exams in multiple languages, and has hundreds of training partners.

Our purpose is to enable economic and creative opportunities for everybody by making open source knowledge and skills certification universally accessible.

  • LinkedIn
  • flogo-RGB-HEX-Blk-58 Facebook
  • Twitter
  • Contact Us
  • Privacy and Cookie Policy

Spot a mistake or want to help improve this page? Please let us know.

© 1999–2023 The Linux Professional Institute Inc. All rights reserved.