Lesson 9: CSS Selectors - Targeting Elements Precisely

What You'll Learn

  • Element, class, and ID selectors
  • Descendant and child selectors
  • Attribute selectors
  • Pseudo-classes (hover, focus, active, etc.)
  • Pseudo-elements (before, after, first-letter)
  • Selector specificity and precedence

Why This Matters

Selectors are how you target elements for styling. Mastering selectors gives you precise control over your styles and helps you write efficient, maintainable CSS.


Part 1: Basic Selectors

Element Selector

p {
    color: blue;
}

h1 {
    font-size: 32px;
}

Targets all elements of that type.

Class Selector

.highlight {
    background-color: yellow;
}

.button {
    padding: 10px 20px;
}
HTML:
<p class="highlight">This is highlighted.</p>
<button class="button">Click Me</button>
Multiple classes:
<div class="card featured">...</div>

ID Selector

#header {
    background-color: navy;
}

#main-content {
    max-width: 1200px;
}
HTML:
<header id="header">...</header>
<div id="main-content">...</div>

Important: IDs should be unique per page!

Universal Selector

* {
    margin: 0;
    padding: 0;
}

Targets ALL elements. Use sparingly!


Part 2: Combining Selectors

Multiple Selectors (Grouping)

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

Applies same styles to multiple selectors.

Element with Class

p.highlight {
    background-color: yellow;
}

div.container {
    max-width: 1200px;
}

Only targets <p> elements with class "highlight".

Multiple Classes

.button.primary {
    background-color: blue;
}

Targets elements with BOTH classes:

<button class="button primary">Click</button>

Part 3: Relationship Selectors

Descendant Selector (Space)

article p {
    line-height: 1.6;
}

Targets ALL <p> elements inside <article>, at any level.

HTML:
<article>
    <p>Styled</p>
    <div>
        <p>Also styled</p>
    </div>
</article>

Child Selector (>)

article > p {
    font-weight: bold;
}

Targets ONLY direct children <p> elements.

HTML:
<article>
    <p>Styled (direct child)</p>
    <div>
        <p>NOT styled (grandchild)</p>
    </div>
</article>

Adjacent Sibling (+)

h2 + p {
    font-size: 1.2em;
}

Targets <p> that comes IMMEDIATELY after <h2>.

HTML:
<h2>Heading</h2>
<p>This is styled</p>
<p>This is NOT styled</p>

General Sibling (~)

h2 ~ p {
    color: gray;
}

Targets ALL <p> siblings after <h2>.


Part 4: Attribute Selectors

Has Attribute

a[target] {
    color: red;
}

Targets links with a target attribute.

Exact Value

a[href="https://example.com"] {
    font-weight: bold;
}

input[type="text"] {
    border: 1px solid gray;
}

Contains Value

a[href*="youtube"] {
    color: red;
}

Targets links containing "youtube" anywhere in href.

Starts With

a[href^="https"] {
    color: green;
}

Targets links starting with "https".

Ends With

a[href$=".pdf"] {
    background: url('pdf-icon.png') no-repeat;
}

Targets links ending with ".pdf".


Part 5: Pseudo-Classes

Pseudo-classes target elements in a specific state.

Link States

a:link {
    color: blue;  / Unvisited link /
}

a:visited {
    color: purple;  / Visited link /
}

a:hover {
    color: red;  / Mouse over /
}

a:active {
    color: orange;  / Being clicked /
}

Order matters! Use: LVHA (Link, Visited, Hover, Active)

Focus

input:focus {
    border-color: blue;
    outline: 2px solid lightblue;
}

button:focus {
    box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.5);
}

When element has keyboard focus.

First/Last Child

li:first-child {
    font-weight: bold;
}

li:last-child {
    border-bottom: none;
}

Nth Child

li:nth-child(odd) {
    background-color: #f0f0f0;
}

li:nth-child(even) {
    background-color: white;
}

li:nth-child(3) {
    color: red;  / Third item /
}

li:nth-child(3n) {
    color: blue;  / Every 3rd item /
}

Other Useful Pseudo-Classes

/ No children /
p:empty {
    display: none;
}

/ Only child /
p:only-child {
    margin: 0;
}

/ Not selector /
li:not(.special) {
    color: gray;
}

/ Checked (for checkboxes/radio) /
input:checked {
    outline: 2px solid green;
}

/ Disabled /
input:disabled {
    opacity: 0.5;
}

Part 6: Pseudo-Elements

Pseudo-elements style specific parts of elements.

::before and ::after

.quote::before {
    content: '"';
    font-size: 2em;
    color: gray;
}

.quote::after {
    content: '"';
    font-size: 2em;
    color: gray;
}
HTML:
<p class="quote">This is a quote</p>

Output: "This is a quote"

Decorative Elements

.heading::before {
    content: "★ ";
    color: gold;
}

.external-link::after {
    content: " ↗";
    font-size: 0.8em;
}

::first-letter

p::first-letter {
    font-size: 3em;
    font-weight: bold;
    float: left;
    margin-right: 5px;
}

Creates drop cap effect.

::first-line

p::first-line {
    font-weight: bold;
    color: #333;
}

Styles only the first line of text.

::selection

::selection {
    background-color: yellow;
    color: black;
}

Styles highlighted/selected text.


Part 7: Specificity

When multiple rules target the same element, specificity determines which wins.

Specificity Hierarchy

From lowest to highest:
  1. Element selectors: p { }
  2. Class selectors: .class { }
  3. ID selectors: #id { }
  4. Inline styles: <p style="...">
  5. !important (avoid if possible)

Calculating Specificity

Count:

  • IDs (worth 100 points)
  • Classes, attributes, pseudo-classes (worth 10 points)
  • Elements, pseudo-elements (worth 1 point)
Examples:
p { }                    / Specificity: 1 /
.button { }              / Specificity: 10 /
p.button { }             / Specificity: 11 /
#header { }              / Specificity: 100 /
#header .nav { }         / Specificity: 110 /
div#header .nav a { }    / Specificity: 112 /

The !important Override

p {
    color: blue !important;
}

Avoid !important - it makes CSS hard to maintain!


Part 8: Complete Example

HTML:
<!DOCTYPE html>
<html>
<head>
    <title>Selector Demo</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <header id="main-header">
        <h1>My Website</h1>
        <nav>
            <a href="/">Home</a>
            <a href="/about">About</a>
            <a href="/contact">Contact</a>
            <a href="https://external.com" target="_blank">External</a>
        </nav>
    </header>
    
    <main>
        <article class="post featured">
            <h2>First Post</h2>
            <p class="intro">This is the introduction paragraph.</p>
            <p>This is a regular paragraph.</p>
            <p>Another paragraph here.</p>
        </article>
        
        <article class="post">
            <h2>Second Post</h2>
            <p>Content for second post.</p>
        </article>
    </main>
    
    <ul class="items">
        <li>Item 1</li>
        <li>Item 2</li>
        <li class="special">Item 3</li>
        <li>Item 4</li>
        <li>Item 5</li>
    </ul>
</body>
</html>
CSS:
/ Element selectors /
body {
    font-family: Arial, sans-serif;
    line-height: 1.6;
    color: #333;
}

/ ID selector /
#main-header {
    background-color: #2c3e50;
    padding: 20px;
    color: white;
}

/ Descendant selector /
#main-header h1 {
    margin: 0;
    font-size: 28px;
}

#main-header nav {
    margin-top: 10px;
}

/ Child selector with pseudo-class /
nav > a {
    color: white;
    text-decoration: none;
    margin-right: 15px;
}

nav > a:hover {
    text-decoration: underline;
}

/ Attribute selector /
a[target="_blank"]::after {
    content: " ↗";
    font-size: 0.8em;
}

/ Class selectors /
.post {
    margin: 20px 0;
    padding: 20px;
    border: 1px solid #ddd;
}

.post.featured {
    border-color: #3498db;
    border-width: 3px;
}

/ Adjacent sibling /
h2 + p {
    font-size: 1.1em;
    color: #555;
}

/ Pseudo-element /
.intro::first-letter {
    font-size: 2em;
    font-weight: bold;
    color: #3498db;
}

/ Nth-child /
.items li:nth-child(odd) {
    background-color: #f0f0f0;
}

.items li:first-child {
    font-weight: bold;
}

.items li:last-child {
    border-bottom: 2px solid #333;
}

/ Not selector /
.items li:not(.special) {
    color: #666;
}

.items li.special {
    color: #e74c3c;
    font-weight: bold;
}

Practice Exercises

Exercise 1: Navigation Styling

Create a navigation menu with:

  • Different styles for visited/unvisited links
  • Hover effects
  • Active link highlighting
  • External link indicators using ::after

Exercise 2: Form Styling

Style a form using:

  • Different styles for different input types
  • Focus states for inputs
  • Disabled input styling
  • Checked checkbox/radio styling

Exercise 3: Article Styling

Create an article with:

  • Drop cap on first paragraph using ::first-letter
  • Different styles for first paragraph
  • Alternating background colors using :nth-child
  • Quote styling with ::before and ::after

What You Learned

  • ✅ Basic selectors (element, class, ID)
  • ✅ Relationship selectors (descendant, child, sibling)
  • ✅ Attribute selectors
  • ✅ Pseudo-classes (:hover, :focus, :nth-child, etc.)
  • ✅ Pseudo-elements (::before, ::after, ::first-letter)
  • ✅ Selector specificity
  • ✅ How to target elements precisely

What's Next?

In the next lesson, you'll learn about CSS Positioning - how to place elements exactly where you want them on the page!