DEV Community

Cover image for CSS Selectors 101: The Complete Guide
Mohammad Aman
Mohammad Aman

Posted on

CSS Selectors 101: The Complete Guide

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;
}
Enter fullscreen mode Exit fullscreen mode

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... -->
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode
  • 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;
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

Result:

  • Both <h1> elements: dark green, centered

  • Both <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;
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

Result:

  • Elements with class="highlight": yellow background, bold

  • Element with class="warning": red text, red border

Multiple Classes: Elements can have multiple classes:

<p class="highlight warning">Important highlighted warning!</p>
Enter fullscreen mode Exit fullscreen mode
.highlight {
  background-color: yellow;
}

.warning {
  color: red;
  border: 2px solid red;
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

Example:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

Example: With Grouping (Clean!)

h1, h2, h3 {
  color: navy;
  font-family: Arial, sans-serif;
}
Enter fullscreen mode Exit fullscreen mode

Mixed Selector Types

h1, .special-text, #unique-paragraph {
  text-transform: uppercase;
  letter-spacing: 2px;
}
Enter fullscreen mode Exit fullscreen mode

This applies the same style to:

  • All <h1> elements

  • All 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)
Enter fullscreen mode Exit fullscreen mode

1. Descendant Selector (Space)

Selects all elements that are descendants (children, grandchildren, etc.) of a specified element.

Syntax:

ancestor descendant {
  property: value;
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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; }
Enter fullscreen mode Exit fullscreen mode

3. Adjacent Sibling Selector (+)

Selects an element that is immediately after another specific element (same parent).

Syntax:

element1 + element2 {
  property: value;
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode
<a href="page.html">Normal link</a>
<a href="page.html" target="_blank">Styled link (has target attribute)</a>
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode
<input type="text" placeholder="Name">
<input type="email" placeholder="Email">
<input type="submit" value="Send">
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode
<img src="forest.jpg" alt="beautiful nature landscape">  <!-- Matched -->
<img src="city.jpg" alt="urban cityscape">  <!-- Not matched -->
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode
<a href="https://secure-site.com">Secure link (green)</a>
<a href="http://old-site.com">Old link (orange)</a>
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

6. Contains Substring: [attribute*="value"]

Selects elements where the attribute contains a specific substring anywhere.

a[href*="example"] {
  font-weight: bold;
}
Enter fullscreen mode Exit fullscreen mode
<a href="https://example.com">Styled</a>
<a href="https://myexamplesite.org">Styled</a>
<a href="https://other.com">Not styled</a>
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode
<div lang="en">Styled</div>
<div lang="en-US">Styled</div>
<div lang="en-GB">Styled</div>
<div lang="fr">Not styled</div>
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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 */
}
Enter fullscreen mode Exit fullscreen mode

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 */
}
Enter fullscreen mode Exit fullscreen mode

Diagram: Selector Targeting Flow

Image 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 */
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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; }
Enter fullscreen mode Exit fullscreen mode

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; }
/* ... */
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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)

  1. Inline styles - style="color: red"

  2. IDs - #header

  3. Classes, attributes, pseudo-classes - .intro, [type="text"], :hover

  4. Elements, pseudo-elements - p, ::before

  5. Universal 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)