CSS Selectors Complete Guide – Types, Examples, Best Practices
CSS selectors are the foundation of styling on the web. They allow you to target HTML elements and apply styles. Whether you are a complete beginner or brushing up your skills, this guide covers every type of selector with clear examples.
What is a CSS Selector?
A CSS selector is the first part of a CSS rule. It tells the browser which elements to style. For example, p { color: red; } selects all paragraph elements.
Basic Selectors
Element Selector
Targets all instances of a given HTML element.
h1 { font-size: 2rem; }
Class Selector
Targets elements with a specific class attribute. Prefixed with a dot.
.highlight { background: yellow; }
ID Selector
Targets a single element with a given ID. Prefixed with #.
#logo { width: 150px; }
Universal Selector
Targets every element in the document. Use with caution.
* { margin: 0; }
Attribute Selectors
Style elements based on attributes or attribute values.
[attr]– element has attribute[attr="value"]– exact value[attr^="value"]– starts with[attr$="value"]– ends with[attr*="value"]– contains substring
a[target="_blank"] { color: red; }
input[type="email"] { border: 2px solid blue; }
Grouping Selectors
Apply the same styles to multiple selectors by separating them with commas.
h1, h2, h3 { font-family: 'Georgia', serif; }
Combinators
Combinators define a relationship between selectors.
- Descendant combinator (space):
div p– selects allpinsidediv - Child combinator (>):
ul > li– direct children only - Adjacent sibling (+):
h2 + p– firstpimmediately afterh2 - General sibling (~):
h2 ~ p– all siblings afterh2
.container > .box { border: 1px solid #ccc; }
Pseudo-classes
They select elements based on state or position.
:hover– on mouse over:focus– when focused:nth-child(n)– nth child:first-child:last-child:not(selector)– negation
a:hover { text-decoration: underline; }
li:nth-child(2n) { background: #f0f0f0; }
Pseudo-elements
They target parts of an element.
::before– insert content before::after– insert content after::first-line– first line of a block::first-letter– first letter
.tooltip::after { content: " ⓘ"; }
p::first-line { font-weight: bold; }
Specificity and the Cascade
When multiple selectors target the same element, specificity decides which style wins. ID selectors (0,1,0,0) beat class selectors (0,0,1,0) beat element selectors (0,0,0,1). Inline styles and !important override normal rules. Learn more in our CSS Specificity and Cascade Tutorial.
Best Practices
- Use classes for reusable styles; avoid IDs in CSS unless necessary.
- Keep selectors as short as possible to improve performance and readability.
- Use combinators sparingly; deep nesting can cause maintenance issues.
- Prefer semantic class names (e.g.,
.btn-primaryover.red-button).
/* Element selector */
body { font-family: Arial, sans-serif; }
/* Class selector */
.card { background: white; border-radius: 8px; }
/* ID selector */
#main-header { background: #333; }
/* Attribute selector */
input[type="text"] { border: 1px solid #aaa; }
/* Pseudo-class */
.card:hover { box-shadow: 0 4px 8px rgba(0,0,0,0.1); }
/* Pseudo-element */
.card::before { content: "📌"; margin-right: 5px; }
/* Combinator */
.card .title { font-size: 1.5rem; }
Conclusion
Mastering CSS selectors is the first step toward building beautiful, maintainable web pages. Practice with different combinations and inspect elements in your browser's DevTools to see which selectors are applied. For hands-on projects, check out our HTML/CSS project tutorials.