Selectors are the foundation of CSS—they tell the browser which HTML elements to style. Think of selectors as the "address" that CSS uses to find and apply styles to specific elements on your page. Mastering selectors is essential for writing effective CSS.
What Are CSS Selectors?
A CSS selector is a pattern that matches one or more HTML elements. When the browser finds elements that match the selector, it applies the styles in the declaration block to those elements.
/* Selector → { Styles } */
h1 {
color: blue;
}
/* The selector (h1) targets all <h1> elements
The declaration block { color: blue; } applies to them */There are several types of selectors in CSS. In this lesson, we'll cover the four most fundamental ones:
- Element Selectors - Target HTML elements by tag name
- Class Selectors - Target elements with specific class attributes
- ID Selectors - Target a single unique element by ID
- Universal Selector - Target all elements on the page
Element Selectors (Type Selectors)
Element selectors target HTML elements by their tag name. They're the simplest and most straightforward selectors—if you want to style all paragraphs, all headings, or all links, element selectors are your tool.
Syntax
/* Just use the element name without any special characters */
elementname {
property: value;
}
/* Examples */
p {
color: gray;
}
h1 {
font-size: 32px;
}
a {
color: blue;
text-decoration: underline;
}How Element Selectors Work
When you use an element selector, the browser finds every instance of that element on the page and applies the styles to all of them.
Element Selectors in Action
Common Element Selectors
Popular Element Selectors
| Property | Values | Description |
|---|---|---|
p | Paragraphs | Selects all <p> elements |
h1, h2, h3 | Headings | Selects all heading elements |
a | Links | Selects all <a> elements |
div | Divisions | Selects all <div> elements |
span | Spans | Selects all <span> elements |
ul, ol | Lists | Selects all list elements |
li | List Items | Selects all <li> elements |
img | Images | Selects all <img> elements |
button | Buttons | Selects all <button> elements |
input | Inputs | Selects all <input> elements |
When to Use Element Selectors
- Base styling: Setting default styles for common elements
- Typography: Styling all headings, paragraphs, or links consistently
- Reset styles: Removing default browser styles
- Global element styles: When you want all instances styled the same
/* Base typography for entire site */
body {
font-family: 'Segoe UI', Arial, sans-serif;
font-size: 16px;
line-height: 1.6;
color: #333;
}
/* All headings bold */
h1, h2, h3, h4, h5, h6 {
font-weight: bold;
margin-bottom: 1rem;
}
/* All paragraphs */
p {
margin-bottom: 1rem;
}
/* All links */
a {
color: #007bff;
transition: color 0.3s;
}
a:hover {
color: #0056b3;
}
/* All images responsive */
img {
max-width: 100%;
height: auto;
}Remember: Element selectors have low specificity, which means they're easily overridden by class and ID selectors. This makes them perfect for base styles that you might want to customize later with more specific selectors.
Class Selectors
Class selectors target elements that have a specific class attribute. They're the most commonly used selectors in CSS because they're reusable—you can apply the same class to multiple elements, and you can apply multiple classes to a single element.
Syntax
/* Use a dot (.) followed by the class name */
.classname {
property: value;
}
/* Examples */
.highlight {
background-color: yellow;
}
.text-center {
text-align: center;
}
.btn-primary {
background-color: blue;
color: white;
}How Class Selectors Work
In HTML, you add a class attribute to elements. In CSS, you target those classes with a dot prefix.
Class Selectors in Action
Multiple Classes on One Element
You can apply multiple classes to a single element by separating them with spaces. This is extremely powerful for creating flexible, reusable styles.
<!-- Element with multiple classes -->
<button class="btn btn-primary btn-large">
Large Primary Button
</button>
<p class="text-center text-bold text-large">
Centered, bold, large text
</p>
<div class="card shadow rounded">
Card with shadow and rounded corners
</div>/* Base button styles */
.btn {
padding: 10px 20px;
border: none;
cursor: pointer;
}
/* Button color variations */
.btn-primary {
background-color: blue;
color: white;
}
.btn-secondary {
background-color: gray;
color: white;
}
/* Button size variations */
.btn-large {
padding: 15px 30px;
font-size: 18px;
}
.btn-small {
padding: 5px 10px;
font-size: 12px;
}
/* Text utilities */
.text-center {
text-align: center;
}
.text-bold {
font-weight: bold;
}
.text-large {
font-size: 20px;
}
/* Visual utilities */
.shadow {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.rounded {
border-radius: 8px;
}Class Naming Best Practices
- Use lowercase with hyphens:
.my-classnot.myClassor.MyClass - Be descriptive:
.primary-buttonnot.btn1 - Keep names semantic:
.warningnot.red-text - Avoid presentational names:
.text-largeis okay, but.margin-20ties you to specific values - Use meaningful prefixes:
.js-togglefor JavaScript hooks
/* Good: Descriptive, semantic names */
.primary-button { }
.warning-message { }
.user-profile-card { }
.navigation-menu { }
/* Avoid: Non-descriptive or presentational */
.btn1 { }
.red { }
.margin-20 { }
.left { }
/* Good: Component-based naming (BEM style) */
.card { }
.card__header { }
.card__body { }
.card--featured { }
/* Good: Utility classes */
.text-center { }
.flex { }
.hidden { }
.mt-4 { } /* margin-top: 1rem */When to Use Class Selectors
- Reusable components: Buttons, cards, forms
- Style variations: Primary vs secondary buttons
- Utility classes: Text alignment, spacing
- State classes: .active, .disabled, .hidden
- Most styling needs: Classes are your go-to selector
💡 Pro Tip:
Classes are the workhorse of CSS. In professional development, you'll use classes for about 80-90% of your styling needs. They strike the perfect balance between specificity and reusability.
ID Selectors
ID selectors target a single unique element with a specific id attribute. Each ID should only appear once per page, making ID selectors very specific and powerful—but also less flexible than class selectors.
Syntax
/* Use a hash (#) followed by the ID name */
#idname {
property: value;
}
/* Examples */
#header {
background-color: navy;
}
#main-content {
max-width: 1200px;
}
#footer {
text-align: center;
}How ID Selectors Work
In HTML, you add an id attribute to a single element. In CSS, you target that specific ID with a hash prefix.
ID Selectors in Action
IDs vs Classes: Key Differences
| Aspect | ID (#) | Class (.) |
|---|---|---|
| Uniqueness | Must be unique per page | Can be reused multiple times |
| Specificity | Very high (harder to override) | Medium (easy to override) |
| Per Element | Only one ID per element | Multiple classes allowed |
| JavaScript | Easy to target with getElementById() | Targeted with getElementsByClassName() |
| URL Linking | Can link with #id-name | Cannot link to classes |
| Best Use | Unique page sections, JavaScript hooks | Styling, reusable components |
When to Use ID Selectors
- Unique page sections: Header, footer, main navigation
- JavaScript targeting: Elements you'll manipulate with JS
- URL fragment links: Jump links to specific page sections
- Form labels: Linking labels to form inputs
<!-- Page sections -->
<header id="header">...</header>
<nav id="main-navigation">...</nav>
<main id="content">...</main>
<footer id="footer">...</footer>
<!-- Jump link targets -->
<a href="#contact-section">Jump to Contact</a>
<!-- Later on the page -->
<section id="contact-section">...</section>
<!-- Form associations -->
<label for="email-input">Email:</label>
<input type="email" id="email-input">
<!-- JavaScript hooks -->
<button id="submit-button">Submit</button>
<div id="modal-container"></div>Important: While IDs work perfectly for styling, many developers prefer classes for CSS because of specificity issues. IDs have very high specificity, making them harder to override later. Reserve IDs for truly unique elements and consider using classes for most styling needs.
The Specificity Problem with IDs
/* ID selector - very high specificity */
#submit-button {
background-color: blue;
}
/* This won't work - class has lower specificity than ID */
.button-green {
background-color: green; /* Won't apply! */
}
/* You'd need to use the ID or increase specificity */
#submit-button.button-green {
background-color: green; /* This works */
}
/* Or use !important (not recommended) */
.button-green {
background-color: green !important; /* Works but bad practice */
}Universal Selector
The universal selector matches every element on the page. It's written as an asterisk (*) and is useful for applying base styles or resets to all elements at once.
Syntax
/* Use an asterisk (*) */
* {
property: value;
}
/* Example */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}Common Uses
The universal selector is most commonly used for CSS resets and applying consistent box-sizing:
/* Reset all default margins and padding */
* {
margin: 0;
padding: 0;
}
/* Apply border-box to all elements */
* {
box-sizing: border-box;
}
/* Common reset pattern */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Can be combined with pseudo-elements */
*,
*::before,
*::after {
box-sizing: border-box;
}Universal Selector in Action
Performance Considerations
Performance Note: While the universal selector isn't as slow as it once was in older browsers, it still matches every single element on the page. Use it sparingly—typically just for resets at the beginning of your stylesheet. Avoid using it in complex selectors or multiple times throughout your CSS.
When to Use the Universal Selector
- CSS resets: Removing default browser styles
- Box-sizing: Applying border-box to all elements
- Base styling: Setting universal defaults
- Debugging: Adding borders to see element boundaries
/* Common reset pattern */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Debugging helper - see all element boundaries */
* {
outline: 1px solid red; /* Remove after debugging */
}
/* Setting base font smoothing */
* {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* Avoid overusing */
/* Bad: */
* {
color: red;
font-family: Arial;
line-height: 1.6;
}
/* Better: Use body for base typography */
body {
color: #333;
font-family: Arial, sans-serif;
line-height: 1.6;
}Combining Multiple Selectors
You can group multiple selectors together to apply the same styles to different elements. This keeps your CSS DRY (Don't Repeat Yourself).
Grouping Selectors
Separate multiple selectors with commas to apply the same styles to all of them:
/* Instead of this: */
h1 {
color: navy;
font-weight: bold;
}
h2 {
color: navy;
font-weight: bold;
}
h3 {
color: navy;
font-weight: bold;
}
/* Do this: */
h1, h2, h3 {
color: navy;
font-weight: bold;
}
/* Mixing element, class, and ID selectors */
h1,
h2,
.title,
#main-heading {
font-family: Georgia, serif;
margin-bottom: 1rem;
}
/* All text elements */
p,
span,
li,
a {
line-height: 1.6;
}
/* All form inputs */
input,
textarea,
select,
button {
font-family: inherit;
font-size: 16px;
}Grouped Selectors Example
Selector Best Practices
1. Prefer Classes for Styling
/* Good: Use classes for most styling */
.button {
padding: 10px 20px;
background-color: blue;
}
.button-primary {
background-color: blue;
}
.button-secondary {
background-color: gray;
}
/* Avoid: Overusing IDs for styling */
#button1 {
padding: 10px 20px;
background-color: blue;
}
#button2 {
padding: 10px 20px;
background-color: gray;
}2. Use Semantic Names
/* Good: Semantic, meaning-based names */
.warning-message { }
.primary-button { }
.user-profile { }
/* Avoid: Presentational names */
.red-text { }
.big-font { }
.left-box { }3. Keep Selectors Simple
/* Good: Simple, direct selectors */
.card { }
.card-title { }
.button { }
/* Avoid: Overly complex selectors */
div#content section.main article.post div.card p.title { }4. Balance Specificity
- Use element selectors for base styles
- Use classes for most component styling
- Reserve IDs for unique page sections and JavaScript
- Avoid over-specific selectors
🎯 Golden Rule:
When in doubt, use a class. Classes provide the best balance of specificity, reusability, and maintainability. They're flexible enough for most situations and specific enough to override element selectors when needed.
Complete Practical Example
Let's build a simple webpage using all four basic selector types:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Basic Selectors Example</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<!-- ID for unique page section -->
<header id="site-header">
<h1>My Blog</h1>
<nav>
<a href="#home">Home</a>
<a href="#about">About</a>
<a href="#contact">Contact</a>
</nav>
</header>
<!-- ID for main content area -->
<main id="content">
<!-- Classes for reusable components -->
<article class="post">
<h2 class="post-title">Understanding CSS Selectors</h2>
<p class="post-meta">Posted on December 24, 2024</p>
<p>This is the main content of the blog post...</p>
<button class="btn btn-primary">Read More</button>
</article>
<article class="post featured">
<h2 class="post-title">Featured Article</h2>
<p class="post-meta">Posted on December 23, 2024</p>
<p class="highlight">This is a featured post with special styling.</p>
<button class="btn btn-secondary">Read More</button>
</article>
</main>
<!-- ID for footer -->
<footer id="site-footer">
<p>© 2024 My Blog. All rights reserved.</p>
</footer>
</body>
</html>/* Universal selector - reset and base styles */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Element selectors - base typography */
body {
font-family: 'Segoe UI', Arial, sans-serif;
line-height: 1.6;
color: #333;
background-color: #f4f4f4;
}
h1, h2 {
color: #2c3e50;
}
a {
color: #3498db;
text-decoration: none;
transition: color 0.3s;
}
a:hover {
color: #2980b9;
}
/* ID selectors - unique page sections */
#site-header {
background-color: #2c3e50;
color: white;
padding: 2rem;
text-align: center;
}
#site-header nav {
margin-top: 1rem;
}
#site-header nav a {
color: white;
margin: 0 15px;
padding: 5px 10px;
}
#content {
max-width: 800px;
margin: 2rem auto;
padding: 0 2rem;
}
#site-footer {
background-color: #34495e;
color: white;
text-align: center;
padding: 1.5rem;
margin-top: 3rem;
}
/* Class selectors - reusable components */
.post {
background: white;
padding: 2rem;
margin-bottom: 2rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.post-title {
font-size: 24px;
margin-bottom: 10px;
}
.post-meta {
color: #7f8c8d;
font-size: 14px;
margin-bottom: 15px;
}
.highlight {
background-color: #fff3cd;
padding: 10px;
border-left: 4px solid #ffc107;
margin: 15px 0;
}
.btn {
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
transition: opacity 0.3s;
}
.btn:hover {
opacity: 0.9;
}
.btn-primary {
background-color: #3498db;
color: white;
}
.btn-secondary {
background-color: #95a5a6;
color: white;
}
.featured {
border: 2px solid #f39c12;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}Key Takeaways
- Selectors tell CSS which HTML elements to style
- Element selectors target all instances of an HTML element
- Class selectors (.) target elements with specific class attributes
- ID selectors (#) target a single unique element
- Universal selector (*) targets all elements on the page
- Classes can be reused; IDs should be unique per page
- Multiple classes can be applied to a single element
- Group selectors with commas to apply the same styles
- Classes are the most commonly used selector in professional CSS
- ID selectors have very high specificity (harder to override)
- Use semantic, descriptive names for classes and IDs
What's Next?
Now that you've mastered basic selectors, you're ready to explore more advanced targeting techniques. In the next lesson, we'll learn about combinators—special selectors that let you target elements based on their relationships with other elements (parent-child, siblings, etc.). This will give you even more precision and control over your styling!
Understanding basic selectors is fundamental—they're the building blocks you'll use in every CSS file you write. Practice using element, class, and ID selectors, and you'll quickly develop an intuition for which selector to use in different situations.