CSS Selectors 101: Targeting Elements with Precision

When we write CSS, we don’t style everything at once. We choose which HTML elements should get specific styles. That “choosing” is done using CSS selectors.
Why CSS Selectors Are Needed ?
Imagine a webpage with:
Headings
Paragraphs
Buttons
Images
If CSS had no selectors, every style would apply to every element, which wouldn’t give us any benefits rather it will be chaos.
CSS selectors allow us to:
Target specific elements
Apply styles precisely
Keep CSS clean and manageable
CSS Selector
Think of selectors like addressing people:
Element selector → “Everyone in this room”
Class selector → “All students wearing a blue uniform”
ID selector → “That one person named Rahul”
Descendant selector → “Students sitting in the last bench”
CSS works the same way—it selects elements based on how you describe them.
Now take a look at each type of selector —
Element Selector
An element selector select element by tag name and select all elements with that tag name. Example —
p { color: blue; }What it does
Selects all
<p>elementsApplies blue color to every paragraph
Class Selector
A class selector selects html element with specific class name and select all element with that class. Example —
.highlight { background-color: yellow; }<p class="highlight">Important text</p> <p>Normal text</p>What it does
Only elements with
class="highlight"are styledMultiple elements can share the same class
Use classes when:
You want to style many elements
Reuse styles across the page
Note: In one element there can be multiple classes.
Id Selector
An ID selector targets one unique element.
Syntax
#id-name { property: value; }Example
#main-title { color: red; }<h1 id="main-title">Welcome</h1>Key rule
IDs must be unique on a page.
Use IDs when:
Styling a single, unique element
Working with JavaScript later
Group Selector
A group selector allows us to apply the same CSS rules to multiple elements at once.
Instead of writing separate CSS for each element, we group them together and write the style only once.
Think of it like saying: “Apply this style to all of these elements.”
Syntax of Group Selector
Multiple selectors are separated using a comma (,).
selector1, selector2, selector3 { property: value; }Note: The comma is mandatory.
Without it, CSS will interpret the selector differently.Simple Example
h1, h2, p { color: blue; }What this means
Selects all
<h1>elementsSelects all
<h2>elementsSelects all
<p>elementsApplies the same color to all of them
<h1>Main Heading</h1>
<h2>Sub Heading</h2>
<p>This is a paragraph</p>
All three elements become blue.
Why Group Selectors Are Useful ?
Without a group selector, you would write:
h1 {
font-family: Arial;
}
h2 {
font-family: Arial;
}
p {
font-family: Arial;
}
With a group selector:
h1, h2, p {
font-family: Arial;
}
Benefits
Reduces repeated code
Makes CSS cleaner
Easier to maintain
Follows DRY principle (Don’t Repeat Yourself)
Descendant Selector
A descendant selector is used to target elements that are inside another element, no matter how deeply they are nested.
It allows CSS to say: “Style this element only when it exists inside another specific element.”
Syntax of Descendant Selector
ancestor descendant { property: value; }Ancestor → the parent (or outer) element
Descendant → the element inside it
There is a space between them (this space is important)
Simple Example
div p {
color: green;
}
What this means
Selects all
<p>elementsBut only those inside a
<div>
<div>
<p>This paragraph will be green</p>
</div>
<p>This paragraph will NOT be green</p>
Only the paragraph inside the <div> gets the style.
How It Works Internally
CSS reads the selector from left to right:
Find all
<div>elementsInside them, find
<p>elementsApply styles only to those
<p>elements
Why Descendant Selectors Are Needed ?
Descendant selectors help:
Apply context-based styling
Avoid unnecessary classes
Keep styles scoped to specific sections
Example use cases:
Styling text inside a navbar
Styling list items inside a sidebar
Styling paragraphs inside an article
Example with Deeper Nesting
section div p {
font-size: 18px;
}
This targets:
<p>inside<div><div>inside<section>
Even if the <p> is deeply nested, it still gets styled.
Rules of Descendant Selectors
- Space between selectors is mandatory
div p { }
- Descendants don’t have to be direct children
<div>
<section>
<p>Still selected</p>
</section>
</div>
- You can combine different selector types
#content .card p {
color: blue;
}
- Overusing descendant selectors can slow readability
Keep them short and meaningful
Avoid very long chains
Common Mistake
❌ Wrong (no space):
divp {
color: red;
}
❌ Wrong expectation:
div > p
This is a child selector, not a descendant selector.
Correct:
div p {
color: red;
}
When to Use Descendant Selectors
Use them when:
Styling elements based on where they appear
Working with layouts or sections
You want scoped styling without extra classes
Avoid when:
Selector chains become too long
A class would be clearer
Basic Selector Priority
Sometimes, multiple CSS selectors target the same HTML element. When this happens, CSS must decide: Which style should be applied? This decision is made using selector priority, also known as CSS specificity. At a very basic level, some selectors are stronger than others.
Simple Priority Order
CSS follows this order (from weakest to strongest):
Element selector < Class selector < ID selector
Or simply:
Element selector → lowest priority
Class selector → medium priority
ID selector → highest priority
Easy Example
p {
color: blue;
}
.text {
color: green;
}
#special {
color: red;
}
<p id="special" class="text">Hello World</p>
What happens?
The element matches all three selectors
CSS chooses the strongest one
Final color: Red
Because ID selector has the highest priority.
CSS Selector Specificity Table
The following table outlines the different selector categories, examples, and their corresponding specificity weight:
| Selector Category | Example | Specificity Weight (A, B, C, D) | Notes |
| Inline Styles | <p style="color: pink;"> | (1, 0, 0, 0) | Highest priority, overrides all other selectors except !important. |
| ID Selectors | #navbar | (0, 1, 0, 0) | Second highest priority. |
| Classes, Attributes, and Pseudo-classes | .test, [type="text"], :hover | (0, 0, 1, 0) | Third highest priority. |
| Elements and Pseudo-elements | h1, ::before, ::after | (0, 0, 0, 1) | Lowest priority (excluding universal selector). |
| Universal Selector | * | (0, 0, 0, 0) | No specificity value. |
The !important rule is used to give the value of a specific property the highest priority. It will override ALL previous styling rules for that specific property on that element!
Summary
In this article, we learned how CSS selectors help us choose specific HTML elements and apply styles in a controlled way. We explored different types of selectors such as element, class, ID, group, and descendant selectors, along with their use cases and basic rules. We also understood basic selector priority, which decides which style is applied when multiple selectors target the same element. Overall, selectors form the foundation of CSS and are essential for writing clean, scalable, and maintainable stylesheets.
Thank you for reading & Happy Coding 👨💻
References
MDN Web Docs – CSS Selectors
MDN Web Docs – CSS Specificity




