Mastering CSS Selectors & The Cascade

Frontend Basic Lesson 2 of 5 12 min

Class 2: Understanding How CSS Targets and Styles Your HTML

From Inline Styles to Professional CSS

In Class 1, we used inline styles directly on HTML elements. While this works, it's not maintainable for real projects. Imagine updating the color scheme on a 50-page website where every color is hardcoded in inline styles. You'd have to find and replace thousands of instances.

CSS (Cascading Style Sheets) solves this problem by separating presentation from content. Think of HTML as the structure of a house and CSS as the interior design. The house stands on its own, but CSS makes it beautiful.

Key Insight: Professional web developers keep their CSS in external files. This enables consistency across pages, easier maintenance, and better collaboration with design teams.

What You'll Learn Today

By the end of this class, you'll understand how to target any HTML element with precision, control which styles take priority when conflicts arise, and use modern CSS features like custom properties to build maintainable stylesheets.

Three Ways to Add CSS

CSS can be added to HTML documents in three different ways. Each has its place, but external stylesheets are the professional standard.

1. Inline CSS

Styles applied directly to an element using the style attribute. We used this extensively in Class 1.

This is inline CSS

When to use: Almost never in production. Only for quick tests or when you absolutely need to override other styles.

2. Internal CSS (Style Tag)

CSS written inside a

When to use: Single-page websites or when you want critical CSS to load immediately without an extra HTTP request.

3. External CSS (Preferred Method)

CSS written in a separate file and linked to your HTML. This is the professional standard.

HTML File (index.html)


    

CSS File (styles.css)

p {
    color: blue;
    font-size: 18px;
}
Best Practice: Always use external CSS files for multi-page websites. They load once and are cached by the browser, making subsequent page loads faster.

CSS Selectors: Targeting HTML Elements

Selectors are how you tell CSS which HTML elements to style. Think of them as the addressing system for your webpage. Just like you need an address to send mail to the right house, you need selectors to apply styles to the right elements.

Element Selector

Targets all elements of a specific type. This is the most basic selector.

CSS Code:

p {
    color: #2c3e50;
    line-height: 1.6;
}

Visual Result:

This paragraph has been styled with the element selector. All paragraphs on the page will have dark blue text and comfortable line spacing.

Class Selector (.)

Targets elements with a specific class attribute. Classes are reusable and can be applied to multiple elements. The class selector starts with a period.

CSS Code:

.highlight {
    background: #fff3cd;
    border-left: 4px solid #ffc107;
    padding: 15px;
}

HTML Code:

Important information

Visual Result:

Important information that stands out from regular paragraphs

ID Selector (#)

Targets a single element with a specific ID attribute. IDs must be unique on a page. The ID selector starts with a hash symbol.

CSS Code:

#main-header {
    background: #2c3e50;
    color: white;
    padding: 20px;
    text-align: center;
}

HTML Code:

My Portfolio

Visual Result:

My Portfolio

Important: Use classes for styling, IDs for unique page landmarks and JavaScript hooks. Classes are more flexible because you can reuse them.

Attribute Selector

Targets elements based on their attributes. Very powerful for styling forms, links, and data attributes.

CSS Code:

a[target="_blank"] {
    color: #e74c3c;
}

a[target="_blank"]::after {
    content: " ↗";
}

Visual Result:

Internal link versus External link ↗

Pseudo-Classes

Pseudo-classes target elements in specific states or positions. They start with a colon.

:hover - Triggered when mouse hovers over element

button {
    background: #3498db;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 5px;
}

button:hover {
    background: #2980b9;
    cursor: pointer;
}

Visual Result (hover over the button):

:nth-child() - Targets specific position elements

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

li:nth-child(even) {
    background: #ffffff;
}

Visual Result:

  • First item (odd)
  • Second item (even)
  • Third item (odd)
  • Fourth item (even)

Common Pseudo-Classes Reference

:hover - Element being hovered by mouse
Use for: Interactive feedback on links, buttons
:focus - Element has keyboard focus
Use for: Form inputs, accessibility
:first-child - First child of parent
Use for: Removing top margin from first paragraph
:last-child - Last child of parent
Use for: Removing bottom margin from last element
:nth-child(n) - Specific position or pattern
Use for: Zebra striping tables, every 3rd item

CSS Combinators: Relationships Between Elements

Combinators let you target elements based on their relationship to other elements. This is incredibly powerful for creating precise selectors without adding extra classes.

Descendant Selector (space)

Targets all elements that are descendants (children, grandchildren, etc.) of another element.

CSS Code:

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

What it targets: All elements inside a

Child Selector (>)

Targets only direct children of an element, not deeper descendants.

CSS Code:

ul > li {
    list-style-type: square;
}

HTML Structure:

  • Direct child - styled ✓
  • Direct child - styled ✓
    • Grandchild - NOT styled ✗

Adjacent Sibling Selector (+)

Targets an element that immediately follows another element at the same level.

CSS Code:

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

What it targets: Only the first

that directly follows an

.

Section Title

This first paragraph is larger and gray - it's the adjacent sibling.

This second paragraph is normal style.

General Sibling Selector (~)

Targets all siblings that follow an element, not just the immediate next one.

CSS Code:

h2 ~ p {
    margin-left: 20px;
}

What it targets: All

elements that come after an

at the same level.

Pro Tip: Combinators reduce the need for extra classes. Instead of adding class="intro-paragraph", use h2 + p to style introduction paragraphs automatically.

The Cascade: Understanding Specificity

When multiple CSS rules target the same element, the browser needs to decide which styles to apply. This is where the cascade and specificity come in. Understanding this is crucial for debugging CSS and avoiding frustration.

What is Specificity?

Specificity is how the browser determines which CSS rule wins when multiple rules target the same element. Think of it as a scoring system where more specific selectors get higher scores.

Specificity Hierarchy (Lowest to Highest)

1. Element Selectors
p { color: blue; }
Specificity: 0-0-1
2. Class Selectors
.intro { color: green; }
Specificity: 0-1-0
3. ID Selectors
#header { color: red; }
Specificity: 1-0-0
4. Inline Styles


Specificity: 1-0-0-0 (always wins)

Specificity in Action

CSS Code (multiple rules targeting same element):

p {
    color: blue;              /* Specificity: 0-0-1 */
}

.intro {
    color: green;             /* Specificity: 0-1-0 - WINS */
}

#main-content p {
    color: orange;            /* Specificity: 1-0-1 */
}

#main-content .intro {
    color: purple;            /* Specificity: 1-1-0 - WINS */
}

HTML:

This text will be purple

Visual Result:

This text will be purple (highest specificity wins)

Important: Avoid using !important unless absolutely necessary. It breaks the natural cascade and makes debugging harder. If you find yourself using it often, your CSS architecture needs improvement.

Inheritance

Some CSS properties are inherited from parent elements to children automatically. This is separate from specificity but equally important to understand.

CSS Code:

body {
    font-family: Arial, sans-serif;
    color: #333;
    line-height: 1.6;
}

Result: All text elements inside the body inherit these properties unless specifically overridden. You don't need to set the font-family on every paragraph, heading, and list.

Properties that inherit:
color, font-family, font-size, line-height, text-align
Properties that don't inherit:
margin, padding, border, background, width, height

CSS Custom Properties (Variables)

CSS variables, officially called custom properties, let you store values that you want to reuse throughout your stylesheet. They're like constants in programming but for CSS.

Why Use CSS Variables?

Imagine you use the color #3498db in 50 different places. Your client asks you to change it to a different blue. Without variables, you'd need to find and replace all 50 instances. With variables, you change it once.

Declaring Variables

Variables are declared in the :root selector (which targets the highest level element) and start with two dashes.

:root {
    --primary-color: #3498db;
    --secondary-color: #2ecc71;
    --text-dark: #2c3e50;
    --text-light: #7f8c8d;
    --background: #ecf0f1;
    --spacing-unit: 20px;
}

Using Variables

Access variables using the var() function.

CSS Code:

button {
    background: var(--primary-color);
    color: white;
    padding: var(--spacing-unit);
}

button:hover {
    background: var(--secondary-color);
}

Visual Result:

Complete Color Palette Example

:root {
    /* Colors */
    --primary: #3498db;
    --secondary: #2ecc71;
    --accent: #e74c3c;
    --dark: #2c3e50;
    --light: #ecf0f1;
    
    /* Typography */
    --font-main: 'Georgia', serif;
    --font-heading: 'Arial', sans-serif;
    
    /* Spacing */
    --space-xs: 5px;
    --space-sm: 10px;
    --space-md: 20px;
    --space-lg: 40px;
    
    /* Borders */
    --border-radius: 8px;
}

Visual Color Palette:

Primary
#3498db
Secondary
#2ecc71
Accent
#e74c3c
Dark
#2c3e50
Light
#ecf0f1
Best Practice: Define all your colors, spacing, and commonly used values as CSS variables at the start of your stylesheet. This makes your code more maintainable and consistent.

Class 2 Project: Professional Portfolio with External CSS

Now we'll take the portfolio from Class 1 and convert it to use an external stylesheet with CSS variables, proper selectors, and interactive states.

Project Structure

portfolio/
├── index.html
└── styles.css

Step 1: Create styles.css

/* ===== CSS VARIABLES ===== */
:root {
    /* Color Palette */
    --primary-color: #2c3e50;
    --secondary-color: #3498db;
    --accent-color: #e74c3c;
    --text-dark: #2c3e50;
    --text-light: #7f8c8d;
    --background-light: #ecf0f1;
    --background-white: #ffffff;
    
    /* Typography */
    --font-main: 'Georgia', serif;
    --font-headings: 'Arial', sans-serif;
    --line-height: 1.6;
    
    /* Spacing */
    --spacing-xs: 10px;
    --spacing-sm: 20px;
    --spacing-md: 40px;
    --spacing-lg: 60px;
    
    /* Other */
    --border-radius: 8px;
    --transition-speed: 0.3s;
}

/* ===== RESET & BASE STYLES ===== */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: var(--font-main);
    line-height: var(--line-height);
    color: var(--text-dark);
    background: var(--background-light);
}

/* ===== TYPOGRAPHY ===== */
h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-headings);
    line-height: 1.2;
    margin-bottom: var(--spacing-sm);
}

h1 {
    font-size: 2.5em;
    color: var(--primary-color);
}

h2 {
    font-size: 2em;
    color: var(--primary-color);
    border-bottom: 3px solid var(--secondary-color);
    padding-bottom: 10px;
    margin-bottom: var(--spacing-sm);
}

h3 {
    font-size: 1.5em;
    color: var(--text-dark);
}

p {
    margin-bottom: var(--spacing-sm);
}

/* ===== HEADER ===== */
header {
    background: var(--primary-color);
    color: white;
    padding: var(--spacing-md);
    text-align: center;
}

header h1 {
    color: white;
    margin: 0;
}

header p {
    font-size: 1.2em;
    margin: 10px 0 0 0;
}

/* ===== NAVIGATION ===== */
nav {
    margin-top: var(--spacing-sm);
}

nav ul {
    list-style: none;
    display: flex;
    justify-content: center;
    gap: var(--spacing-sm);
    flex-wrap: wrap;
}

nav a {
    color: white;
    text-decoration: none;
    padding: 10px 15px;
    border-radius: var(--border-radius);
    transition: background var(--transition-speed);
}

nav a:hover {
    background: var(--secondary-color);
}

/* ===== MAIN CONTENT ===== */
main {
    max-width: 800px;
    margin: 0 auto;
    padding: var(--spacing-md);
}

section {
    margin-bottom: var(--spacing-lg);
}

/* ===== ABOUT SECTION ===== */
#about {
    background: var(--background-white);
    padding: var(--spacing-md);
    border-radius: var(--border-radius);
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

#about img {
    width: 200px;
    height: 200px;
    border-radius: 50%;
    object-fit: cover;
    margin-bottom: var(--spacing-sm);
}

/* ===== SKILLS SECTION ===== */
#skills ul {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: var(--spacing-xs);
    list-style: none;
}

#skills li {
    background: var(--background-white);
    padding: 15px;
    border-radius: var(--border-radius);
    border-left: 4px solid var(--secondary-color);
}

/* ===== PROJECTS SECTION ===== */
article {
    background: var(--background-white);
    padding: var(--spacing-md);
    margin-bottom: var(--spacing-sm);
    border-radius: var(--border-radius);
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    transition: transform var(--transition-speed);
}

article:hover {
    transform: translateY(-5px);
    box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}

article h3 {
    color: var(--secondary-color);
}

article a {
    color: var(--secondary-color);
    text-decoration: none;
    font-weight: bold;
}

article a:hover {
    color: var(--accent-color);
    text-decoration: underline;
}

/* ===== FOOTER ===== */
footer {
    background: var(--primary-color);
    color: white;
    text-align: center;
    padding: var(--spacing-md);
    margin-top: var(--spacing-lg);
}

footer h2 {
    color: white;
    border: none;
    margin-top: 0;
}

footer a {
    color: #66b3ff;
    transition: color var(--transition-speed);
}

footer a:hover {
    color: white;
}

/* ===== RESPONSIVE DESIGN ===== */
@media (max-width: 768px) {
    h1 {
        font-size: 2em;
    }
    
    h2 {
        font-size: 1.5em;
    }
    
    nav ul {
        flex-direction: column;
        align-items: center;
    }
    
    main {
        padding: var(--spacing-sm);
    }
}

Step 2: Update index.html




    
    
    John Doe - Web Developer
    



    

John Doe

Full Stack Web Developer

About Me

John Doe professional headshot

I am a passionate web developer with expertise in modern frontend technologies. My journey in web development began with a fascination for creating user-friendly interfaces.

Skills

  • HTML5 & CSS3
  • JavaScript (ES6+)
  • React.js
  • Node.js
  • Responsive Design
  • Git & GitHub

Projects

E-Commerce Platform

Full-stack application built with React and Node.js featuring user authentication and payment processing.

View Project →

Task Management App

Productivity application with real-time updates using WebSockets and team collaboration features.

View Project →

Weather Dashboard

Data visualization project using weather APIs with interactive charts and graphs.

View Project →

Key Improvements

Clean HTML
No inline styles - all styling moved to external CSS file
CSS Variables
Easy to update colors, spacing, and fonts from one location
Hover Effects
Navigation links and project cards respond to user interaction
Transitions
Smooth animations make the site feel more professional
Responsive Design
Media queries ensure the site looks good on all devices

Testing Your Project

  1. Create a folder called "portfolio"
  2. Save the HTML code as "index.html"
  3. Save the CSS code as "styles.css" in the same folder
  4. Open index.html in your browser
  5. Test all hover effects on navigation and project links
  6. Resize your browser window to test responsive behavior

Validation Checklist

  • CSS file is properly linked in the HTML head
  • CSS variables are defined in :root selector
  • All colors use CSS variables (no hardcoded hex values in styles)
  • Navigation links have hover states
  • Project links have hover states
  • Project cards have hover animations
  • Typography is consistent and readable
  • No inline styles remain in HTML (except for demonstrations)

Complete this lesson

Mark as complete to track your progress