MGU Computer Science Series — Web Development: HTML, CSS, and JavaScript
Part III: CSS — Style and Layout
Selectors · Inheritance · Specificity · Cascade
Chapter 12 of 30
12
MGU Computer Science Series  ·  Web Development: HTML, CSS, and JavaScript  ·  Library Textbook Edition

Chapter 12:
Selectors, Properties,
and the Cascade

How CSS chooses which elements to style — type, class, and ID selectors, grouping and descendant selectors, pseudo-classes, inheritance, specificity, and the cascade that resolves every style conflict

■ Part III of VII ■

■ 11 Sections  •  Chapter 12 of 30 ■

Builds directly on Chapter 11 — assumes a working external stylesheet linked to an HTML page

Chapter Introduction and Learning Objectives

In Chapter 11 you wrote your first stylesheet, linked it to an HTML page, and saw how CSS rules connect to HTML elements. You learned the basic shape of a rule: a selector, a declaration block, a property, and a value.

But CSS becomes complicated quickly once you have more than a handful of rules. What happens when two rules both try to style the same element? What happens when a child element inherits a color from its parent but you want to override it? What happens when a class rule and a type rule both apply at the same time?

These are not edge cases. They happen on every real website, often many times per page. Understanding how CSS resolves these conflicts is one of the most important skills in front-end development, and it is the subject of this chapter.

This chapter teaches you how CSS selects elements, how selector types differ, how inheritance works, how specificity determines which rule wins, and how source order matters when specificity is tied. Together these ideas form the cascade — the algorithm CSS uses to decide which style applies when multiple rules compete.

Opening Question

Two CSS rules both set the color of the same paragraph. One rule uses a class selector. The other uses a type selector and appears later in the file. Which rule wins, and why? By the end of this chapter, you will be able to answer that question for any pair of conflicting rules — instantly, and with confidence, using nothing more than the structure of the selectors themselves.

11Sections
12Objectives
11Key Terms
30Total Chapters

Learning Objectives

By the end of this chapter, you should be able to:

  1. 1Explain how CSS selectors determine which elements on a page receive a rule's declarations.
  2. 2Distinguish between type, class, and ID selectors, and decide when each is the right choice.
  3. 3Write grouped selectors to apply shared declarations to multiple selectors efficiently.
  4. 4Write descendant selectors to target elements based on where they appear in the document, and recognize the risks of overly deep nesting.
  5. 5Apply pseudo-classes such as :hover, :focus, :first-child, :last-child, and :nth-child() to style elements by state or position.
  6. 6Explain inheritance and identify which CSS properties typically inherit from parent to child.
  7. 7Calculate the specificity of a selector using the (A, B, C) model.
  8. 8Predict which rule wins when multiple rules with different specificities target the same element and property.
  9. 9Explain how source order resolves conflicts when two rules have equal specificity.
  10. 10Describe the three-step cascade algorithm: origin and importance, specificity, and source order.
  11. 11Identify common selector and specificity mistakes — including overused IDs and careless use of !important — and correct them.
  12. 12Trace a realistic stylesheet conflict from selectors, through specificity, to a final resolved style.

Sections at a Glance

Sections 12.1 – 12.4
The Basics: How Selectors Target Elements
Type Selectors · Class Selectors · ID Selectors

How CSS Selects Elements

Every CSS rule begins with a selector. The selector tells the browser which elements in the HTML document the rule applies to.

You already know the simplest form: writing the element name selects every element of that type.

p { color: #333333; }

This rule applies to every <p> element on the page. It does not apply to headings, links, list items, or anything else — only paragraphs.

But real pages have complex structures. You often want to style some paragraphs differently from others, or style an element only when it appears inside a certain container, or change the style of a link when the user hovers over it. CSS provides many types of selectors to handle these situations.

Before studying each type individually, it helps to understand what a selector actually does. When the browser loads a page, it reads all of the CSS and builds an internal map: for each element on the page, which rules apply? The browser uses the selector to answer that question.

Think of a selector as a filter or a question. The selector p asks: "Is this element a paragraph?" The selector .highlight asks: "Does this element have the class highlight?" The selector nav a asks: "Is this element an anchor that lives inside a nav?"

Every element on the page is tested against every selector. If the element matches, the rule's declarations apply. If the element does not match, the declarations are ignored for that element.

Key Idea

CSS rules do not apply to the whole page. They apply to individual elements that match the selector. Understanding selectors means understanding which elements match, and which do not.

Type Selectors

A type selector targets every element of a given HTML tag name. It is the most basic kind of selector.

h1 { font-size: 2rem; } p { line-height: 1.6; } a { color: #0057a8; } ul { padding-left: 1.5rem; }

Each of these rules applies to every element of that type, anywhere on the page.

Type selectors are powerful because they establish baseline styles across the entire document. You typically use them for setting foundational typographic styles: heading sizes, paragraph spacing, link colors, list padding.

When Type Selectors Work Well

Type selectors are best when the style should apply globally. If all <h2> elements on your site should be a specific size, a type selector for h2 is the right choice. If all links should share a base color, a type selector for a is appropriate.

When Type Selectors Become a Problem

Type selectors become a problem when you need variation. Imagine a page with both a navigation menu and a list of article tags. Both are built with <ul> and <li> elements. If you write:

li { font-size: 0.9rem; color: #555555; }

This rule will apply to both the navigation items and the article tags. But you probably want the navigation items to be styled differently from the tags. A type selector alone cannot make that distinction. This is exactly why more specific selectors exist.

Class Selectors

A class selector targets any element that has been given a specific class attribute in the HTML. Class selectors are written with a dot (.) followed by the class name.

.highlight { background-color: #fff9c4; }

This rule applies to any element — regardless of its tag — that has class="highlight" in the HTML.

<p class="highlight">This paragraph has a yellow background.</p> <span class="highlight">This span also has a yellow background.</span> <div class="highlight">So does this div.</div>

All three elements above will receive the yellow background, even though they are different HTML elements. The class is the shared trait; the type does not matter.

Using Classes for Variation

Classes solve the problem we identified with type selectors. You can style all <p> elements with a base rule, then add a class to modify specific paragraphs.

/* Base style for all paragraphs */ p { color: #333333; line-height: 1.6; } /* Modified style for intro paragraphs */ .intro { font-size: 1.2rem; font-weight: 600; color: #111111; }
<p class="intro">This is the introduction paragraph.</p> <p>This is a normal body paragraph.</p> <p>So is this one.</p>

The first paragraph receives both the base p rules and the .intro rules. The other paragraphs only receive the base p rules.

Multiple Classes on One Element

An element can have more than one class. You separate class names with spaces in the HTML attribute.

.card { border: 1px solid #dddddd; border-radius: 8px; padding: 1.5rem; } .card--featured { border-color: #0057a8; background-color: #f0f6ff; }
<div class="card">A regular card.</div> <div class="card card--featured">A featured card.</div>

The featured card receives styles from both .card and .card--featured. This pattern — combining a base class with a modifier class — is very common in real CSS.

Class Naming Conventions

Class names should be meaningful and describe what the element is or does, not what it looks like. Good class names describe purpose:

.navigation .hero-section .card .alert .form-label .featured

Avoid class names that describe appearance, because if the design changes, the name becomes misleading:

.red-box /* describes color, not purpose */ .big-font /* describes size, not purpose */ .center-text /* describes alignment, not purpose */
A Note on BEM

The double-hyphen naming pattern (.card--featured, .button--large) is part of a methodology called BEM (Block Element Modifier). You will encounter BEM in professional codebases. It is not required at this stage, but it is useful to recognize.

ID Selectors and When to Avoid Overusing Them

An ID selector targets a single element by its id attribute. ID selectors are written with a hash symbol (#) followed by the ID name.

#main-header { background-color: #1a1a2e; color: #ffffff; }
<header id="main-header"> <h1>Student Learning Site</h1> </header>

This rule applies only to the element with id="main-header". No other element on the page will receive this style.

The Rule About IDs

IDs are meant to be unique on a page. An ID should not appear more than once. This is an HTML rule, not just a style convention. If two elements have the same ID, your HTML is technically invalid and browser behavior may become inconsistent.

This uniqueness is also the main limitation of ID selectors for styling. Because an ID can only appear once per page, an ID-based CSS rule can only ever style one element. If you want to style many elements the same way, you need a class.

Why Specificity Is the Bigger Concern

As you will learn in Section 12.9, ID selectors have very high specificity — far higher than class selectors and type selectors. This means that an ID-based rule is extremely difficult to override later. Once you style something with an ID selector, you need an even more specific rule to change it.

This makes ID selectors fragile for styling. Overusing them creates specificity problems that are hard to debug.

When to Use ID Selectors

IDs are appropriate for:

  • JavaScript selection (targeting a specific element to interact with)
  • Anchor targets (linking to a specific section of the page with href="#section-name")
  • Labeling form controls (for="email-input" matching id="email-input")
Study Note

For CSS styling, prefer class selectors. Use ID selectors sparingly in stylesheets, and only when you are certain the element is unique and you will never need to reuse the style.

Sections 12.5 – 12.7
Combining and Extending Selectors
Grouping Selectors · Descendant Selectors · Pseudo-Classes

Grouping Selectors

Sometimes you want to apply the same declarations to multiple different selectors. You can write separate rules, but there is a more efficient option: grouping selectors.

Grouping selectors are written by separating selectors with commas. The declarations inside the rule apply to all listed selectors.

h1, h2, h3 { font-family: Georgia, serif; color: #1a1a2e; }

This is equivalent to writing three separate rules:

h1 { font-family: Georgia, serif; color: #1a1a2e; } h2 { font-family: Georgia, serif; color: #1a1a2e; } h3 { font-family: Georgia, serif; color: #1a1a2e; }

Both produce the same result. The grouped version is shorter and easier to maintain. If you want to change the font family for all three headings, you only need to edit one place.

Important Detail: Each Selector Is Independent

Even though the selectors are grouped, each one is independent. They are not linked relationships — they are just a shorthand for writing the same declarations under multiple selectors.

This matters when one selector in a group is invalid. If you write:

h1, h2, ..h3 { color: red; }
Caution

The third selector (..h3) is invalid. Some older browsers would discard the entire rule when they found one invalid selector in a group. Modern browsers are more forgiving, but writing careful, valid CSS remains the better habit.

Style Tip: Format Grouped Selectors on Separate Lines

Professional stylesheets typically put each grouped selector on its own line. This makes the grouping easier to read, easier to edit, and easier to compare.

/* Clear and readable */ h1, h2, h3, h4 { font-weight: 700; } /* Harder to read with many selectors */ h1, h2, h3, h4 { font-weight: 700; }

Either format is valid CSS. The multi-line format is preferred for maintainability.

Descendant Selectors

A descendant selector targets an element only when it appears inside another specific element. You write it by placing a space between two selectors.

nav a { color: #ffffff; text-decoration: none; }

This rule applies only to <a> elements that are descendants of a <nav> element. Anchor elements elsewhere on the page — in paragraphs, in footers, in articles — are not affected.

The word "descendant" is important. An element is a descendant if it is nested anywhere inside the ancestor, not just directly inside. It does not matter how many levels deep.

<nav> <ul> <li><a href="index.html">Home</a></li> <li><a href="about.html">About</a></li> </ul> </nav> <p>Read more <a href="lessons.html">in the lessons section</a>.</p>

The anchor inside the <nav> matches nav a. The anchor inside the <p> does not match — it has no <nav> ancestor.

Descendant Selectors Add Precision

The most common use of descendant selectors is to style elements differently based on where they appear. Navigation links are often styled differently from body text links. List items inside a footer may be styled differently from list items inside the main content.

/* All links: blue and underlined */ a { color: #0057a8; text-decoration: underline; } /* Links inside the navigation: white and no underline */ nav a { color: #ffffff; text-decoration: none; } /* Links inside the footer: light gray */ footer a { color: #aaaaaa; }

This pattern is clean and organized. A base style is set for all links. Then specific contexts override that base style.

A Caution About Deep Nesting

Descendant selectors work at any depth, which can become a problem. Writing main section article div p a { color: red; } targets anchors nested six levels deep. This is technically valid but almost never appropriate. Deep descendant selectors are fragile (if the HTML structure changes slightly, the selector stops matching), difficult to read and maintain, and high in specificity, which makes them harder to override. Prefer shorter descendant selectors — two levels is common, three is sometimes appropriate, and more than that is usually a sign the selector should be replaced with a class.

Pseudo-Classes at an Introductory Level

Sometimes you need to style an element not based on what it is, but based on its state or position. A link might need a different color when the user hovers over it. A button might need a visible outline when it is focused with a keyboard. The first item in a list might need different spacing from the others.

CSS handles these situations with pseudo-classes. A pseudo-class is added to a selector using a colon (:), followed by the pseudo-class name.

Hover: Responding to the Mouse

The :hover pseudo-class applies styles when the user's cursor is over the element.

a { color: #0057a8; text-decoration: underline; } a:hover { color: #003d7a; text-decoration: none; }

When the user moves their cursor over a link, the browser applies the :hover styles. When the cursor leaves, the :hover styles are removed and the base styles return. Hover effects are very common for links, buttons, navigation items, and cards. They give users visual feedback that an element is interactive.

Focus: Keyboard Navigation and Accessibility

The :focus pseudo-class applies when an element receives keyboard focus — typically when a user tabs to it or clicks on a form field.

input:focus { outline: 2px solid #0057a8; outline-offset: 2px; } a:focus { outline: 2px solid #0057a8; outline-offset: 2px; }

Focus styles are critically important for accessibility. Users who navigate with keyboards — including people with motor disabilities, power users, and those without a mouse — rely on visible focus indicators to know where they are on the page.

Never Remove Focus Styles Without Replacing Them

This is one of the most common accessibility mistakes in web development.

/* DO NOT DO THIS */ a:focus { outline: none; }

Removing the outline makes the page visually cleaner for mouse users but nearly unusable for keyboard users. If you want a custom focus style, replace it with something equally visible:

/* This is fine — replacing the outline, not removing it */ a:focus { outline: 2px solid #ff6b35; outline-offset: 3px; }

First-Child and Last-Child: Position in a List

The :first-child pseudo-class selects an element that is the first child of its parent. The :last-child pseudo-class selects an element that is the last child.

li { border-bottom: 1px solid #dddddd; } li:last-child { border-bottom: none; }

This is a common pattern for lists: add a dividing line below each item, then remove it from the last item so the list does not end with a stray border.

Nth-Child: Selecting by Position

The :nth-child() pseudo-class selects elements based on their numeric position. You pass a number, a keyword, or a formula inside the parentheses.

/* Select every even row */ tr:nth-child(even) { background-color: #f8f8f8; } /* Select every odd row */ tr:nth-child(odd) { background-color: #ffffff; }

This creates alternating row colors in a table — a pattern called zebra striping, which makes long tables easier to read.

/* Select the third item */ li:nth-child(3) { font-weight: bold; }

You will work more with :nth-child() in later chapters. For now, knowing that it exists and understanding its basic use is sufficient.

Other Commonly Used Pseudo-Classes

Pseudo-ClassApplies To
:visitedLinks the user has already visited
:activeAn element during the moment a user clicks it
:checkedChecked checkboxes and radio buttons
:disabledForm elements that are disabled
:not()Elements that do not match the argument inside the parentheses

You will see these in context as the course progresses. The pattern — selector followed by colon followed by pseudo-class name — is the same for all of them.

Sections 12.8 – 12.10
The Cascade: Inheritance, Specificity, and Source Order
How CSS Resolves Every Conflict

Inheritance

CSS inheritance is the mechanism by which certain CSS properties automatically pass from parent elements to their child elements, without you writing any rule for the children.

Consider this example:

body { font-family: Georgia, serif; color: #333333; line-height: 1.7; }

You are styling the <body> element — the outermost container for all visible page content. Every <p>, <h1>, <li>, <td>, and other element inside <body> is a descendant of <body>.

Because font-family, color, and line-height are inherited properties, all those descendant elements automatically receive the same font family, color, and line height. You do not need to repeat those declarations on every element.

This is one of the most useful features in CSS. You can set foundational typographic styles once on the body or a major container, and they flow through the entire document.

Which Properties Are Inherited?

Not all properties inherit. Properties related to text and typography typically do. Properties related to spacing, borders, and layout typically do not.

Properties That InheritProperties That Do Not Inherit
colorbackground-color
font-familyborder
font-sizemargin
font-weightpadding
font-stylewidth
line-heightheight
text-aligndisplay
text-transformposition
letter-spacingbox-shadow
visibility, cursor 

The reasoning is sensible. If you put a border around a <div>, you almost certainly do not want every element inside that <div> to also have a border. If you set a background color, you probably do not want all children to share it. But if you set a text color, you usually do want all the text inside a container to use that color unless otherwise specified.

Inheritance Is Not the Same as Applying a Rule

Inheritance is a fallback. If an element has a specific rule targeting it, that rule takes priority over inherited values. Inheritance only takes effect when no more specific rule applies.

body { color: #333333; } h1 { color: #1a1a2e; }

The <body> rule sets color to dark gray. All elements inherit this — paragraphs, list items, spans, and others will be dark gray. But <h1> has its own rule with a darker navy color. The specific h1 rule takes priority, so headings will be navy, not the inherited dark gray.

The inherit Keyword

If you ever need to explicitly force an element to inherit a property, you can use the value inherit.

a { color: inherit; }

This is useful in situations where the browser applies a default link color (usually blue) that overrides the inherited parent color. Writing color: inherit forces the anchor to use whatever color its parent provides.

Specificity

When two or more CSS rules target the same element and set the same property, a conflict exists. The browser cannot apply both values. It must choose one. The rule that wins is determined by specificity.

Specificity is a numeric weight assigned to a selector. A selector with higher specificity wins over a selector with lower specificity, regardless of which rule appears first in the stylesheet.

Calculating Specificity

CSS specificity is calculated using three categories, often represented as three numbers: (A, B, C).

A — ID selectors. Each ID selector in the selector string contributes 1 to the A value.

B — Class selectors, attribute selectors, and pseudo-classes. Each class selector (.highlight), attribute selector ([type="text"]), or pseudo-class (:hover) contributes 1 to the B value.

C — Type selectors and pseudo-elements. Each type selector (p, h1, a) or pseudo-element (::before, ::after) contributes 1 to the C value.

The universal selector (*) contributes nothing — its specificity is (0, 0, 0).

Comparing Specificity

To compare two selectors, read the A values first. The higher A value wins. If A values are equal, read the B values. The higher B value wins. If B values are also equal, read the C values. The higher C value wins.

Only if all three values are equal does source order matter (which you will learn about in Section 12.10).

Worked Specificity Examples
Three increasingly complex conflicts
  • Example 1p has specificity (0, 0, 1). .intro has specificity (0, 1, 0). For a <p class="intro">, both have A = 0, so compare B: .intro has B = 1, p has B = 0. .intro wins — the paragraph color is #111111.
  • Example 2.card a and nav .link both have specificity (0, 1, 1) — exactly equal. For an element matching both, source order decides: whichever rule appears later in the stylesheet wins.
  • Example 3For a <p class="highlight" id="intro">, three rules apply: p at (0,0,1), .highlight at (0,1,0), and #intro at (1,0,0). The ID selector wins because A = 1, the highest value among the three. The color is navy.

A Visual Model for Specificity

Some developers picture specificity like a three-digit number where each digit represents one category. This is not perfectly accurate mathematically (ten class selectors do not beat one ID selector), but it helps with intuition.

SelectorABC
p001
.intro010
p.intro011
nav a002
nav .link011
#header100
#header nav a102
Specificity Guidelines for Good CSS

Most experienced developers follow a consistent pattern: use type selectors for global, foundational styles (reset, base typography); use class selectors for component and pattern styles; use ID selectors sparingly, and only for truly unique structural elements; and avoid deep compound selectors, which create high specificity that is hard to override. The more you rely on class selectors, the easier your CSS is to maintain and override. When specificity is predictable, debugging becomes much simpler.

Source Order and the Cascade

You have now learned three factors that affect which CSS rule wins a conflict: the origin of the rule (browser defaults, author styles, user styles), specificity, and source order. Together these form the cascade.

The cascade is the algorithm CSS uses to resolve all style conflicts. Here is how it works, in order:

The Three Steps of the Cascade

Step 1 — Origin and importance. Rules can come from multiple sources: the browser's built-in stylesheet, the page author's stylesheet, and user preferences. Author styles (the CSS files you write) typically override browser defaults. Rules marked with !important can override this order, but !important should be used very sparingly.

Step 2 — Specificity. Among rules from the same origin, higher specificity wins.

Step 3 — Source order. Among rules with equal specificity, the rule that appears later in the stylesheet wins.

Source Order in Practice

When specificity is equal, later rules override earlier rules.

p { color: #333333; } /* This rule appears later with equal specificity */ p { color: #111111; }

The second p rule wins because it appears later. The color will be #111111. This is why the order of your CSS rules matters. If you want one style to be the default and another to be an override, write the override later in the file.

Source Order and Linked Stylesheets

Source order also applies across multiple <link> elements in the HTML. If you link two stylesheets, the one linked second can override the one linked first (assuming equal specificity).

<link rel="stylesheet" href="css/base.css"> <link rel="stylesheet" href="css/theme.css">

Rules in theme.css can override rules in base.css if specificity is equal. This is a useful pattern for organizing stylesheets: write foundational styles in a base file, then write overrides in a theme or page-specific file.

A Complete Cascade Example

Let us trace through a realistic example using all three cascade factors.

HTML
<article id="featured-post" class="card"> <p class="intro">Welcome to the course.</p> </article>
CSS
/* Rule 1 */ p { color: #555555; font-size: 1rem; } /* Rule 2 */ .intro { color: #222222; font-size: 1.1rem; } /* Rule 3 */ .card p { color: #333333; } /* Rule 4 */ #featured-post .intro { color: #0057a8; }

For the <p class="intro"> element inside the article, all four rules match. Let us trace the color conflict:

RuleSelectorSpecificityColor Value
Rule 1p(0, 0, 1)#555555
Rule 2.intro(0, 1, 0)#222222
Rule 3.card p(0, 1, 1)#333333
Rule 4#featured-post .intro(1, 1, 0)#0057a8

Rule 4 has A = 1 (one ID), which is highest. The color is #0057a8. For font-size, only Rules 1 and 2 set that property. Rule 2 has higher specificity, so font-size is 1.1rem. This is how every CSS conflict resolves: the browser collects all matching rules for each property, evaluates them through the cascade, and applies the winner.

!important — Handle with Care

You can mark any declaration with !important to override the normal cascade.

p { color: red !important; }

This declaration will override any other rule setting the color of <p> elements, regardless of specificity or source order — with one exception: another !important declaration with higher specificity will still win.

A Specificity Arms Race

!important is occasionally useful — for example, in utility classes that must never be overridden, or in external style overrides where you cannot change the original stylesheet. But using it carelessly creates a specificity arms race: you use !important to override something, then something else uses !important to override your override. The cascade becomes unpredictable. Good CSS rarely needs !important. If you find yourself reaching for it regularly, the root cause is usually a specificity organization problem that would be better solved by restructuring the selectors.

Worked Example: Building a Styled Article Card

Let us apply everything in this chapter to a realistic example. We will build a styled article card step by step, writing selectors intentionally and understanding why each rule applies.

The HTML
<section class="cards"> <article class="card"> <h2 class="card-title">Introduction to HTML</h2> <p class="card-summary">Learn the building blocks of every web page.</p> <a class="card-link" href="lessons/html.html">Start lesson</a> </article> <article class="card card--featured"> <h2 class="card-title">CSS Fundamentals</h2> <p class="card-summary">Discover how to control the look of your pages.</p> <a class="card-link" href="lessons/css.html">Start lesson</a> </article> <article class="card"> <h2 class="card-title">JavaScript Basics</h2> <p class="card-summary">Add interaction and logic to your websites.</p> <a class="card-link" href="lessons/js.html">Start lesson</a> </article> </section>

The CSS is built layer by layer, from the most general rules to the most specific.

Building the Stylesheet
Four layers of increasing specificity
  • Step 1Base type styles (low specificity, foundational). Rules for h2, p, and a apply to every matching element on the page and provide a foundation. Each has specificity (0, 0, 1).
  • Step 2Card component styles (class selectors). .cards, .card, .card-title, .card-summary, and .card-link each target a specific part of the card component, all at a consistent specificity of (0, 1, 0).
  • Step 3Featured card modifier. .card--featured changes the featured card's border and background. .card--featured .card-title has specificity (0, 2, 0) — two class selectors — which is higher than .card-title alone at (0, 1, 0), so the featured card's title correctly shows a different color.
  • Step 4Hover and focus states. Pseudo-classes add one unit to the B value, so .card:hover has specificity (0, 2, 0) — higher than .card at (0, 1, 0). This is correct: hover styles should override base styles.
/* Step 1 — base type styles */ h2 { font-size: 1.25rem; font-weight: 700; margin-bottom: 0.5rem; } p { margin-bottom: 1rem; line-height: 1.6; } a { color: #0057a8; text-decoration: underline; } /* Step 2 — card component styles */ .cards { display: flex; gap: 1.5rem; } .card { background-color: #ffffff; border: 1px solid #dddddd; border-radius: 8px; padding: 1.5rem; } .card-title { color: #1a1a2e; } .card-summary { color: #555555; } .card-link { display: inline-block; font-weight: 600; text-decoration: none; color: #0057a8; } /* Step 3 — featured card modifier */ .card--featured { border-color: #0057a8; background-color: #f0f6ff; } .card--featured .card-title { color: #0057a8; } /* Step 4 — hover and focus states */ .card:hover { border-color: #aaaaaa; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); } .card-link:hover { text-decoration: underline; } .card-link:focus { outline: 2px solid #0057a8; outline-offset: 2px; }

The Complete Cascade Picture

Now, for the <h2 class="card-title"> inside the featured card, three rules apply: h2 at (0,0,1) sets font-size, font-weight, and margin-bottom; .card-title at (0,1,0) sets color: #1a1a2e; and .card--featured .card-title at (0,2,0) sets color: #0057a8.

The font-size, font-weight, and margin-bottom come from the h2 rule because no higher-specificity rule sets those properties. The color comes from .card--featured .card-title because it has the highest specificity among rules that set color. This is the cascade working exactly as intended.

Common Mistakes and How to Fix Them

Mistake 1 — Using too many ID selectors
Writing ID selectors for all major elements creates extremely high specificity, making later overrides nearly impossible.

Fragile: #header { background-color: #1a1a2e; }, #nav { display: flex; }, #footer { background-color: #333333; }

Fix — use class selectors instead: .site-header { background-color: #1a1a2e; }, .site-nav { display: flex; }, .site-footer { background-color: #333333; } Reserve IDs for JavaScript and anchor targets.

Mistake 2 — Overusing !important
Using !important to force a style to apply without understanding why a rule is being overridden: p { color: red !important; }
Investigate the cascade. Find the rule that is winning and understand its specificity. Either increase the specificity of your intended rule legitimately, or reduce the specificity of the conflicting rule.
Mistake 3 — Confusing descendant selectors with all-elements selectors
Writing nav a intending to style all links, then being confused when links outside of <nav> are not styled.
Understand that nav a only matches anchors inside <nav>. For all links on the page, use a alone.
Mistake 4 — Forgetting that type selectors lose to class selectors
Writing a type selector expecting it to override a class selector: .highlight { color: orange; } followed by p { color: black; } — for a <p class="highlight">, the color will be orange because .highlight has higher specificity than p, regardless of source order.
If you need a type selector to override a class selector, add a class to it, or recognize this is a specificity conflict requiring a different approach entirely.
Mistake 5 — Removing focus styles
a:focus, button:focus, input:focus { outline: none; }
Replace, never remove: a:focus, button:focus, input:focus { outline: 2px solid #0057a8; outline-offset: 3px; }
Mistake 6 — Over-qualified selectors
Writing selectors that are more specific than necessary: div.card p.card-summary a.card-link { color: #0057a8; } has specificity (0, 3, 3), which is unnecessarily high and very hard to override.
Use the shortest selector that correctly targets the element: .card-link { color: #0057a8; }

Chapter Summary

Key Terms

cascade
The algorithm CSS uses to resolve conflicts between rules. It considers rule origin, specificity, and source order to determine which declaration applies to each element.
class selector
A CSS selector that targets elements with a specific value in their class attribute. Written with a dot prefix: .card, .highlight.
descendant selector
A CSS selector that targets an element only when it appears inside another specific element. Written with a space between selectors: nav a, .card p.
grouping selector
A way to apply the same CSS declarations to multiple selectors by separating them with commas: h1, h2, h3 { }.
ID selector
A CSS selector that targets an element with a specific id attribute. Written with a hash prefix: #main-header. Carries very high specificity.
inheritance
The mechanism by which certain CSS properties (particularly typographic ones) automatically pass from parent elements to their descendants.
!important
A CSS keyword that forces a declaration to override the normal cascade. Should be used rarely and with intention.
pseudo-class
A CSS keyword added to a selector using a colon, targeting an element based on its state or position. Examples: :hover, :focus, :first-child.
specificity
A numeric weight assigned to a CSS selector that determines which rule wins when multiple rules target the same element and property. Calculated using three categories: ID selectors, class/attribute/pseudo-class selectors, and type/pseudo-element selectors.
source order
The position of a CSS rule within the stylesheet. When specificity is equal, rules that appear later override rules that appear earlier.
type selector
A CSS selector that targets every element of a given tag name: p, h1, a, ul.
PracticeCode Reading

Read each CSS snippet carefully. Answer the questions that follow without writing any new code.

Exercise 12-CR-1
body { font-family: 'Georgia', serif; color: #333333; line-height: 1.7; } main { font-size: 1rem; } p { margin-bottom: 1.25rem; }
  1. Which CSS properties will a <p> inside <main> inherit from <body>?
  2. Which CSS property will it receive from the main rule?
  3. Which CSS property will it receive from its own p rule?
  4. Will the <p> have the line-height: 1.7 style? Explain why or why not.
Exercise 12-CR-2
a { color: #0057a8; text-decoration: underline; } nav a { color: #ffffff; text-decoration: none; } footer a { color: #aaaaaa; }

For each anchor element below, predict which color it will have:

<nav> <a href="index.html">Home</a> </nav> <main> <p>Read more <a href="about.html">about us</a> here.</p> </main> <footer> <a href="contact.html">Contact</a> </footer>
Exercise 12-CR-3
.button { background-color: #0057a8; color: #ffffff; padding: 0.75rem 1.5rem; border-radius: 4px; } .button:hover { background-color: #003d7a; } .button:focus { outline: 3px solid #ff6b35; outline-offset: 2px; } .button--danger { background-color: #cc0000; } .button--danger:hover { background-color: #990000; }
<button class="button">Submit</button> <button class="button button--danger">Delete</button>
  1. What background color does the first button have at rest?
  2. What background color does the first button have on hover?
  3. What background color does the second button have at rest?
  4. What background color does the second button have on hover?
  5. What is the specificity of .button--danger:hover?
  6. If you added id="confirm-delete" to the second button and wrote #confirm-delete { background-color: navy; }, what background color would the button have at rest?
PracticeCode Tracing
Exercise 12-CT-1

Trace the cascade for the <h2> element below. List each rule that applies, its specificity, and which property values it contributes. State the final value for each conflicting property.

/* Rule A */ h2 { font-size: 1.5rem; color: #333333; font-weight: 700; } /* Rule B */ .section-title { color: #1a1a2e; font-size: 1.75rem; } /* Rule C */ .hero .section-title { color: #ffffff; } /* Rule D */ #intro-heading { font-size: 2rem; }
<section class="hero"> <h2 class="section-title" id="intro-heading">Welcome</h2> </section>
  1. Does Rule A apply? What is its specificity?
  2. Does Rule B apply? What is its specificity?
  3. Does Rule C apply? What is its specificity?
  4. Does Rule D apply? What is its specificity?
  5. What is the final value of font-size? Which rule wins?
  6. What is the final value of color? Which rule wins?
  7. What is the final value of font-weight? Which rule provides it?
Exercise 12-CT-2

A student is building a navigation menu and writes the following CSS rules in order:

/* Line 1 */ a { color: #0057a8; } /* Line 5 */ .nav-link { color: #333333; } /* Line 9 */ a.nav-link { color: #1a1a2e; } /* Line 13 */ .site-nav .nav-link { color: #555555; }
<nav class="site-nav"> <a class="nav-link" href="about.html">About</a> </nav>
  1. List each rule that applies to the <a class="nav-link">, with its specificity.
  2. Which rule wins the color conflict? What color appears?
  3. If the student removes the .site-nav .nav-link rule, which rule wins? What color appears?
  4. If the student then also removes a.nav-link, which rule wins? What color appears?
PracticePredict the Result
Exercise 12-PR-1
p { color: gray; } .intro { color: navy; } p.intro { color: teal; }
<p>A regular paragraph.</p> <p class="intro">An intro paragraph.</p> <div class="intro">An intro div.</div>

Predict the text color for each element. Explain your reasoning using specificity.

Exercise 12-PR-2
li { color: black; } li:first-child { color: red; } li:last-child { color: blue; } li:nth-child(2) { color: green; }
<ul> <li>First</li> <li>Second</li> <li>Third</li> </ul>

Predict the color of each list item. Then explain what would happen if there were only two list items.

Exercise 12-PR-3

This CSS has a conflict. Before reading further, identify which declaration wins and predict what the heading looks like.

/* Stylesheet line 1 */ .article-title { color: #333333; font-size: 1.5rem; } /* Stylesheet line 8 */ main .article-title { color: #0057a8; } /* Stylesheet line 15 */ .article-title { color: #cc0000; font-weight: 600; }
<main> <h2 class="article-title">Lesson One</h2> </main>
  1. Which three rules apply to the <h2>?
  2. What is the specificity of each?
  3. For color: which rule wins? What is the color?
  4. For font-size: which rule provides this value?
  5. For font-weight: which rule provides this value?
PracticeDebugging Practice

Each scenario describes a CSS problem. Identify what is wrong and write a corrected version.

  1. 12-D-1. A student wants the links inside .sidebar to be gray, but all links on the page are turning gray.
    a { color: gray; }
    What did the student do wrong? Write the corrected CSS that only affects sidebar links.
  2. 12-D-2. A student wants their featured article heading to be orange. They write:
    h2 { color: orange; } #featured article h2 { color: navy; }
    The heading appears navy, not orange. The student adds this rule at the bottom of the stylesheet:
    h2 { color: orange; }
    The heading is still navy. Explain why, and suggest a correct fix.
  3. 12-D-3. A student is trying to style alternating rows of a table. They write:
    tr:nth-child(even) { background-color: #f0f0f0; } tr { background-color: #ffffff; }
    Both the even and odd rows appear white. What is wrong? Fix the CSS.
  4. 12-D-4. A student's form inputs look strange on keyboard navigation. They added this rule:
    input, button, a { outline: none; border: none; }
    What is the accessibility problem? Rewrite this CSS to fix the issue.
  5. 12-D-5. A student notices that their card titles inherit the wrong font from a parent element. They try:
    .card h2 { font-family: 'Arial', sans-serif; }
    But the titles are still showing the wrong font. In developer tools, they see the inherited font is being overridden by this rule elsewhere in the stylesheet:
    #lesson-section h2 { font-family: 'Times New Roman', serif; }
    Their HTML is:
    <section id="lesson-section"> <div class="card"> <h2>Lesson One</h2> </div> </section>
    Explain why .card h2 loses. Write a corrected fix using only class selectors.
PracticeShort Build Tasks
  1. 12-B-1. Write CSS that applies the following styles: all <h3> elements get a dark gray color (#222222) and 1.25rem font size; all <p> elements get a medium gray color (#555555), 1rem font size, and 1.6 line height; <p> elements with class .lead get a dark color (#111111) and 1.2rem font size. Test your specificity: the .lead rule must win over the base p rule.
  2. 12-B-2. Write a CSS selector group that applies font-weight: 700 to h1, h2, h3, h4, h5, and h6 — all six heading levels — using one CSS rule.
  3. 12-B-3. Write CSS that styles the navigation of a Student Learning Site: all links blue and underlined; links inside <nav> white and not underlined; links inside <nav> on hover light blue (#a0c8ff) and not underlined; links inside <nav> on focus a 3px solid white outline with 2px offset; links inside <footer> medium gray (#888888) and underlined.
  4. 12-B-4. Given this HTML structure:
    <ul class="tag-list"> <li class="tag">HTML</li> <li class="tag">CSS</li> <li class="tag">JavaScript</li> <li class="tag">Accessibility</li> </ul>
    Write CSS to style all .tag items with background-color: #e8f0fe, border-radius: 12px, padding: 0.25rem 0.75rem, and font-size: 0.875rem; style the first tag with background-color: #1a1a2e and color: #ffffff; and style every even-numbered tag with background-color: #d0e4ff.
  5. 12-B-5. Write a complete stylesheet section for a .card component including: a base .card rule with border, padding, border-radius, and background; a .card:hover rule with a subtle box shadow; a .card--featured modifier with a different border color and background; a .card-title rule with a specific color and font-size; and a .card--featured .card-title rule with a different color to override the base title color. Use only class selectors. Confirm that your specificity planning is correct.
Mixed ReviewDrawing on Chapters 5 – 12
  1. 12-MR-1. You are building a lesson page with this structure:
    <main> <article class="lesson"> <h1 class="lesson-title">Introduction to HTML</h1> <p class="lesson-intro">This lesson covers the basics of HTML structure.</p> <section class="lesson-content"> <h2>What is HTML?</h2> <p>HTML stands for HyperText Markup Language.</p> </section> </article> </main>
    (a) Write a CSS selector to target only the <h2> inside .lesson-content, not any <h2> outside it. (b) Write a CSS selector to target both .lesson-title and .lesson-intro using a grouping selector. (c) What specificity does main article .lesson-title have? (d) What specificity does .lesson .lesson-title have? (e) If both of the above rules set color, which wins?
  2. 12-MR-2. A student writes this HTML and CSS:
    <nav> <ul> <li><a href="index.html" class="active">Home</a></li> <li><a href="about.html">About</a></li> <li><a href="resources.html">Resources</a></li> </ul> </nav>
    nav ul { list-style: none; display: flex; gap: 1rem; padding: 0; } nav a { color: #ffffff; text-decoration: none; font-weight: 500; } nav a:hover { color: #a0c8ff; } .active { color: #ffcc00; font-weight: 700; }
    (a) The .active link is #ffcc00. Does nav a also match this element? What color does the element actually use, and why? (b) If the student wants .active to always win over nav a, is the current specificity sufficient? Show your work. (c) On hover, the .active link does not turn #a0c8ff. Explain why. (d) The student wants the active link to remain #ffcc00 even on hover. How would you write that rule?
  3. 12-MR-3. Identify the HTML error and the CSS specificity error in this code, and write corrections.
    <section id="about" id="main-section"> <h2 class="section-heading">About the Course</h2> <p>This course teaches web development foundations.</p> </section>
    #about #main-section .section-heading { color: #1a1a2e; }
ProjectMini-Project: Styled Navigation and Content Section

Apply the selector and cascade skills from this chapter to build a styled page section for the Student Learning Site.

Project Requirements
A navigation bar and a card grid, fully styled with intentional selectors
  • HTMLCreate an index.html file with a <header> containing a <nav> with at least four links (Home, Lessons, Resources, Contact), and a <main> section containing a heading, a short introductory paragraph with class .intro, and a grid of three cards using <article class="card">, each with a title, a short description, and a link.
  • CSSIn css/main.css: set foundational body styles using type selectors (font-family, color, line-height); style navigation links using a descendant selector (nav a) with :hover and :focus states; style .card with a class selector including border, padding, and background, plus a .card:hover shadow or border change; create a .card--featured modifier for one card; style .intro to differ from regular <p> elements; and use a grouped selector for all heading levels that should share a font family.
  • Specificity PlanningWrite a comment in your stylesheet next to each rule indicating its approximate specificity, e.g. /* (0,1,0) */. Verify that modifiers have higher specificity than base classes where needed.
  • AccessibilityProvide visible focus styles on all interactive elements, alt text on any images, and meaningful navigation link text.
Mini-Project Evaluation Checklist
Confirm before submitting
  • No inline styles in the HTML
  • External stylesheet linked correctly
  • All class names are meaningful and descriptive
  • No unnecessary ID selectors in the CSS
  • At least one descendant selector is used correctly
  • At least one pseudo-class is used for hover or focus
  • The featured card modifier overrides the base card using appropriate specificity
  • The .intro rule has higher specificity than the base p rule
  • Focus styles are present and visible
  • Specificity comments are added as described

Accessibility Check

Review your stylesheet and HTML from this chapter's project, or a provided sample page, and answer the following.

  1. Are all interactive elements — links, buttons, form inputs — reachable by keyboard? Tab through the page to test.
  2. Do interactive elements have a visible focus style? Is the focus outline visible against the background?
  3. Does any CSS rule use outline: none without replacing it? If so, fix it.
  4. Are heading levels in the correct order (h1 → h2 → h3, not skipping levels)?
  5. If any colored text appears on a colored background, is there sufficient contrast? (Light gray text on white fails; dark gray on white passes.)
  6. Does navigation use a <nav> element so screen readers can identify it as a landmark?
Preview — Chapter 13
Colors, Typography, Spacing, and Borders

Chapter 12 gave you full control over which elements your CSS rules affect, and full confidence in predicting how conflicts resolve. With your selector and cascade knowledge now solid, you can write rules knowing exactly which elements they will affect and why.

Chapter 13 turns to the visual properties that make pages readable and appealing: color formats (hex, RGB, HSL), text color, background color, font families, font size, line height, font weight, text alignment, margins, padding, borders, and border radius. You will apply these properties using the selectors from this chapter, building a complete, readable page style for the Student Learning Site.

MGU Library Connection
  • Web Development: HTML, CSS, and JavaScript — Appendix D: CSS Reference
  • Web Development: HTML, CSS, and JavaScript — Appendix M: Full Glossary of Web Development Terms
  • Companion resource: CSS Selector Chart
  • Companion resource: CSS Specificity Guide
  • Companion resource: Browser Developer Tools Guide
  • Next chapter: Chapter 13 — Colors, Typography, Spacing, and Borders