Introduction: What Are CSS Selectors?
Assume CSS selectors as a way to address people in a room. Just like you might say:
"Everyone!" (universal)
"All teachers!" (element type)
"People wearing blue shirts!" (class)
"John Smith specifically!" (ID)
CSS selectors are patterns that allow you to choose which HTML elements you want to style. They are the foundation of CSS and the key to controlling your webpage's appearance.
Anatomy of a CSS Rule
selector {
property: value;
}
The selector tells the browser which elements to target, and the declarations inside the curly braces define how those elements should look.
Why CSS Selectors Are Needed
Without CSS selectors, we would face serious problems:
1. No Way to Target Elements
Imagine wanting to change all paragraph text to blue. Without selectors, you'd need to add inline styles to every single <p> tag:
<!-- Without Selectors - Tedious! -->
<p style="color: blue;">Paragraph 1</p>
<p style="color: blue;">Paragraph 2</p>
<p style="color: blue;">Paragraph 3</p>
<!-- Repeat 100 times... -->
2. Code Duplication
Inline styles mean repeating the same code everywhere, making maintenance a nightmare.
3. Lack of Flexibility
Can't make site-wide changes quickly. Want to change all buttons from blue to green? Good luck editing hundreds of files!
The Solution: CSS Selectors
With selectors, you write the style once and apply it everywhere:
p {
color: blue;
}
One line changes all paragraphs
Easy to maintain
Separation of concerns (HTML structure vs CSS styling)
Basic Selectors
1. Element Selector (Type Selector)
The element selector targets all elements of a specific HTML tag type.
Syntax:
element {
property: value;
}
Example:
<!DOCTYPE html>
<html>
<head>
<style>
p {
color: navy;
font-size: 16px;
}
h1 {
color: darkgreen;
text-align: center;
}
</style>
</head>
<body>
<h1>Welcome to CSS Selectors</h1>
<p>This paragraph will be navy blue.</p>
<p>This paragraph will also be navy blue.</p>
<h1>Another Heading</h1>
</body>
</html>
Result:
Both
<h1>elements: dark green, centeredBoth
<p>elements: navy blue, 16px
Use Cases:
Setting default styles for common elements
Creating consistent typography
Resetting browser defaults
2. Class Selector
The class selector targets elements with a specific class attribute. Classes can be reused on multiple elements.
Syntax:
.classname {
property: value;
}
Real-World Analogy: Like grouping people by their role (teachers, students, staff)
Example:
<!DOCTYPE html>
<html>
<head>
<style>
.highlight {
background-color: yellow;
font-weight: bold;
}
.warning {
color: red;
border: 2px solid red;
padding: 10px;
}
</style>
</head>
<body>
<p class="highlight">This text is highlighted.</p>
<p>This is normal text.</p>
<p class="highlight">This is also highlighted.</p>
<div class="warning">Warning: Check your input!</div>
</body>
</html>
Result:
Elements with
class="highlight": yellow background, boldElement with
class="warning": red text, red border
Multiple Classes: Elements can have multiple classes:
<p class="highlight warning">Important highlighted warning!</p>
.highlight {
background-color: yellow;
}
.warning {
color: red;
border: 2px solid red;
}
Both styles apply to the element!
3. ID Selector
The ID selector targets a single unique element. IDs must be unique within a page.
Syntax:
#idname {
property: value;
}
Real-World Analogy: Like calling someone by their unique name (only one "John Smith" in the room)
Example:
<!DOCTYPE html>
<html>
<head>
<style>
#header {
background-color: #333;
color: white;
padding: 20px;
text-align: center;
}
#main-content {
margin: 20px;
line-height: 1.6;
}
</style>
</head>
<body>
<div id="header">
<h1>My Website</h1>
</div>
<div id="main-content">
<p>Welcome to the main content area.</p>
</div>
</body>
</html>
Important Rules:
NEVER use the same ID twice on a page
Use IDs for unique elements (header, footer, main navigation)
Use classes for reusable styles
4. Universal Selector
The universal selector targets ALL elements on the page.
Syntax:
* {
property: value;
}
Example:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
This is commonly used for CSS resets to ensure consistent styling across browsers.
Warning: Use sparingly as it affects every element!
Group Selectors
Group selectors allow you to apply the same styles to multiple selectors, reducing code duplication.
Syntax:
selector1, selector2, selector3 {
property: value;
}
Example: Without Grouping (Repetitive)
h1 {
color: navy;
font-family: Arial, sans-serif;
}
h2 {
color: navy;
font-family: Arial, sans-serif;
}
h3 {
color: navy;
font-family: Arial, sans-serif;
}
Example: With Grouping (Clean!)
h1, h2, h3 {
color: navy;
font-family: Arial, sans-serif;
}
Mixed Selector Types
h1, .special-text, #unique-paragraph {
text-transform: uppercase;
letter-spacing: 2px;
}
This applies the same style to:
All
<h1>elementsAll elements with
class="special-text"The element with
id="unique-paragraph"
Combinator Selectors
Combinators allow you to select elements based on their relationship to other elements in the HTML structure.
Visual Hierarchy
div (parent)
├── p (child)
├── span (child)
│ └── strong (grandchild)
└── p (child)
1. Descendant Selector (Space)
Selects all elements that are descendants (children, grandchildren, etc.) of a specified element.
Syntax:
ancestor descendant {
property: value;
}
Example:
<!DOCTYPE html>
<html>
<head>
<style>
div p {
color: blue;
background-color: lightgray;
}
</style>
</head>
<body>
<p>I am NOT styled (not inside a div)</p>
<div>
<p>I AM styled (direct child of div)</p>
<section>
<p>I AM styled (grandchild of div)</p>
</section>
</div>
</body>
</html>
Result:
First
<p>: normal (not inside a<div>)Second
<p>: blue text, gray background (child of<div>)Third
<p>: blue text, gray background (grandchild of<div>)
2. Child Selector (>)
Selects elements that are direct children only (not grandchildren).
Syntax:
parent > child {
property: value;
}
Example:
<!DOCTYPE html>
<html>
<head>
<style>
div > p {
color: red;
font-weight: bold;
}
</style>
</head>
<body>
<div>
<p>I AM styled (direct child)</p>
<section>
<p>I am NOT styled (grandchild, not direct child)</p>
</section>
</div>
</body>
</html>
Descendant vs. Child Comparison:
/* Descendant - selects ALL p elements inside div */
div p { color: blue; }
/* Child - selects ONLY direct child p elements */
div > p { color: red; }
3. Adjacent Sibling Selector (+)
Selects an element that is immediately after another specific element (same parent).
Syntax:
element1 + element2 {
property: value;
}
Example:
<!DOCTYPE html>
<html>
<head>
<style>
h2 + p {
font-style: italic;
color: gray;
}
</style>
</head>
<body>
<h2>Heading One</h2>
<p>This paragraph is styled (immediately after h2)</p>
<p>This paragraph is NOT styled (not immediately after h2)</p>
<h2>Heading Two</h2>
<p>This paragraph is styled (immediately after h2)</p>
</body>
</html>
Common Use Case: Styling the first paragraph after a heading differently.
4. General Sibling Selector (~)
Selects all siblings that come after a specified element (same parent).
Syntax:
element1 ~ element2 {
property: value;
}
Example:
<!DOCTYPE html>
<html>
<head>
<style>
h2 ~ p {
background-color: lightyellow;
}
</style>
</head>
<body>
<p>Not styled (before h2)</p>
<h2>Main Heading</h2>
<p>Styled (after h2)</p>
<p>Styled (after h2)</p>
<div>Not a paragraph</div>
<p>Styled (after h2)</p>
</body>
</html>
Difference from Adjacent (+):
+selects only the next immediate sibling~selects all following siblings
Attribute Selectors
Attribute selectors target elements based on their attributes or attribute values.
1. Presence: [attribute]
Selects elements that have a specific attribute.
a[target] {
background-color: yellow;
}
<a href="page.html">Normal link</a>
<a href="page.html" target="_blank">Styled link (has target attribute)</a>
2. Exact Match: [attribute="value"]
Selects elements with an attribute that exactly matches a value.
input[type="text"] {
border: 2px solid blue;
}
input[type="submit"] {
background-color: green;
color: white;
}
<input type="text" placeholder="Name">
<input type="email" placeholder="Email">
<input type="submit" value="Send">
3. Contains Word: [attribute~="value"]
Selects elements where the attribute contains a specific word in a space-separated list.
img[alt~="nature"] {
border: 3px solid green;
}
<img src="forest.jpg" alt="beautiful nature landscape"> <!-- Matched -->
<img src="city.jpg" alt="urban cityscape"> <!-- Not matched -->
4. Starts With: [attribute^="value"]
Selects elements where the attribute value starts with a specific string.
a[href^="https"] {
color: green;
}
a[href^="http://"] {
color: orange;
}
<a href="https://secure-site.com">Secure link (green)</a>
<a href="http://old-site.com">Old link (orange)</a>
5. Ends With: [attribute$="value"]
Selects elements where the attribute value ends with a specific string.
a[href$=".pdf"] {
background: url(pdf-icon.png) no-repeat left center;
padding-left: 20px;
}
a[href$=".jpg"],
a[href$=".png"] {
color: purple;
}
6. Contains Substring: [attribute*="value"]
Selects elements where the attribute contains a specific substring anywhere.
a[href*="example"] {
font-weight: bold;
}
<a href="https://example.com">Styled</a>
<a href="https://myexamplesite.org">Styled</a>
<a href="https://other.com">Not styled</a>
7. Starts With (Hyphenated): [attribute|="value"]
Selects elements where the attribute value is exactly the value or starts with the value followed by a hyphen.
div[lang|="en"] {
color: blue;
}
<div lang="en">Styled</div>
<div lang="en-US">Styled</div>
<div lang="en-GB">Styled</div>
<div lang="fr">Not styled</div>
Selector Priority & Specificity
When multiple CSS rules target the same element, specificity determines which style wins.
The Specificity Hierarchy
CSS specificity is calculated based on a four-part value system:
[Inline Style, IDs, Classes/Attributes/Pseudo-classes, Elements/Pseudo-elements]
Specificity Weights
| Selector Type | Weight | Example |
|---|---|---|
| Inline style | 1,0,0,0 | <p style="color: red;"> |
| ID | 0,1,0,0 | #header |
| Class | 0,0,1,0 | .highlight |
| Attribute | 0,0,1,0 | [type="text"] |
| Pseudo-class | 0,0,1,0 | :hover |
| Element | 0,0,0,1 |
p, div
|
| Pseudo-element | 0,0,0,1 | ::before |
| Universal | 0,0,0,0 | * |
Calculating Specificity
/* Specificity: 0,0,0,1 */
p {
color: blue;
}
/* Specificity: 0,0,1,0 */
.text {
color: green;
}
/* Specificity: 0,1,0,0 */
#special {
color: red;
}
/* Specificity: 0,0,1,1 */
p.text {
color: orange;
}
/* Specificity: 0,1,1,1 */
p#special.text {
color: purple;
}
The selector with the highest specificity wins!
Visual Example
<!DOCTYPE html>
<html>
<head>
<style>
/* Specificity: 0,0,0,1 */
p {
color: red;
}
/* Specificity: 0,0,1,0 - WINS over element */
.test {
color: green;
}
/* Specificity: 0,1,0,0 - WINS over class */
#demo {
color: blue;
}
/* Specificity: 0,1,1,1 - WINS over ID */
p#demo.test {
color: orange;
}
</style>
</head>
<body>
<p id="demo" class="test">What color am I?</p>
</body>
</html>
Result: The paragraph is orange because p#demo.test has the highest specificity (0,1,1,1).
The !important Exception
Using !important overrides all normal specificity rules:
p {
color: blue !important;
}
#demo {
color: red; /* Won't apply */
}
Warning: Avoid !important except in rare cases. It makes debugging difficult!
Specificity Tie-Breaker: Source Order
When specificity is equal, the last rule wins:
.text {
color: blue;
}
.text {
color: red; /* WINS - appears later */
}
Diagram: Selector Targeting Flow
Best Practices
1. Start Simple, Get Specific
/* Good progression */
p { color: black; } /* Base style */
.intro-text { font-size: 18px; } /* Add variation */
#hero-intro { font-weight: bold; } /* Unique case */
2. Prefer Classes Over IDs for Styling
/* Good - Reusable */
.button {
background-color: blue;
color: white;
}
/* Avoid - Too specific */
#submit-button {
background-color: blue;
color: white;
}
3. Use Semantic Class Names
/* Good - Describes purpose */
.error-message { color: red; }
.success-banner { background: green; }
/* Bad - Describes appearance */
.red-text { color: red; }
.green-box { background: green; }
4. Group Related Selectors
/* Good */
h1, h2, h3, h4, h5, h6 {
font-family: 'Georgia', serif;
line-height: 1.4;
}
/* Bad - Repetitive */
h1 { font-family: 'Georgia', serif; }
h2 { font-family: 'Georgia', serif; }
/* ... */
5. Avoid Over-Specific Selectors
/* Too specific - hard to override */
div#content article.post p.intro span.highlight {
color: red;
}
/* Better - easier to maintain */
.intro-highlight {
color: red;
}
Quick Reference
Basic Selectors
| Selector | Syntax | Example | Selects |
|---|---|---|---|
| Universal | * |
* |
All elements |
| Element | element |
p |
All <p> elements |
| Class | .class |
.intro |
All elements with class="intro"
|
| ID | #id |
#header |
Element with id="header"
|
| Group | selector, selector |
h1, h2, h3 |
All <h1>, <h2>, <h3>
|
Combinators
| Combinator | Syntax | Example | Selects |
|---|---|---|---|
| Descendant | A B |
div p |
All <p> inside <div>
|
| Child | A > B |
div > p |
<p> that are direct children of <div>
|
| Adjacent Sibling | A + B |
h2 + p |
<p> immediately after <h2>
|
| General Sibling | A ~ B |
h2 ~ p |
All <p> after <h2> (siblings) |
Attribute Selectors
| Selector | Syntax | Example | Selects |
|---|---|---|---|
| Has Attribute | [attr] |
[target] |
Elements with target attribute |
| Exact Match | [attr="value"] |
[type="text"] |
Elements where type equals "text" |
| Contains Word | [attr~="value"] |
[title~="flower"] |
title contains word "flower" |
| Starts With | [attr^="value"] |
[href^="https"] |
href starts with "https" |
| Ends With | [attr$="value"] |
[href$=".pdf"] |
href ends with ".pdf" |
| Contains | [attr*="value"] |
[href*="example"] |
href contains "example" |
| Hyphenated | `[attr | ="value"]` | `[lang |
Specificity Priority (Highest to Lowest)
Inline styles -
style="color: red"IDs -
#headerClasses, attributes, pseudo-classes -
.intro,[type="text"],:hoverElements, pseudo-elements -
p,::beforeUniversal selector -
*
Summary
CSS selectors are the foundation of web styling. By mastering:
Basic selectors (element, class, ID) for targeting elements
Group selectors for reducing code duplication
Combinators for selecting based on relationships
Attribute selectors for dynamic targeting
Specificity rules for understanding which styles apply
You'll have complete control over your webpage's appearance. Start with simple selectors and progressively add specificity as needed. Remember: keep it simple, keep it maintainable!
Congratulations! You now have a comprehensive understanding of CSS selectors. Keep practicing, and you'll master the art of precise element targeting!

Top comments (0)