Go beyond basic selectors. Use combinators, attribute selectors, pseudo-classes, and more to target elements with surgical precision.

Combinators

Use combinators to target elements based on their relationship to others: Descendant, Child, Sibling, Adjacent.

/* Descendant - all p inside .container */
.container p { color: blue; }

/* Child - only direct children */
.container > p { color: red; }

/* Adjacent Sibling - p immediately after h2 */
h2 + p { font-weight: bold; }

/* General Sibling - all p after h2 */
h2 ~ p { margin-top: 1rem; }

Try it - Combinator examples

Descendant - styled

Nested descendant - also styled

Descendant - styled

Direct child - red

Nested - not red

Attribute Selectors

Target elements based on attributes. Match exact values, partial strings, prefixes, suffixes.

/* Has attribute */
[disabled] { opacity: 0.5; }

/* Exact value */
input[type="text"] { border: 1px solid blue; }

/* Contains word */
[class~="active"] { font-weight: bold; }

/* Starts with */
a[href^="https"] { color: green; }

/* Ends with */
a[href$=".pdf"] { background: red; }

/* Contains substring */
a[href*="example"] { color: purple; }

Try it - Attribute selectors

Pseudo-Elements

Style specific parts of elements: ::before, ::after, ::first-line, ::first-letter, ::selection.

/* Add content before element */
.icon::before {
  content: "→ ";
  color: var(--primary);
  font-weight: bold;
}

/* Add content after element */
.note::after {
  content: " [Note]";
  color: gray;
}

/* First letter - drop cap */
p::first-letter {
  font-size: 2em;
  font-weight: bold;
  color: var(--primary);
}

/* First line styling */
p::first-line {
  font-weight: bold;
}

Try it - Pseudo-elements in action

Icon element

This is a note

The first line of this paragraph is styled differently. Notice how only the first line gets the special treatment.

This paragraph has a drop cap on the first letter. Try selecting and highlighting the text to see the selection color.

Specificity

CSS applies based on specificity. Inline styles (1000) beat IDs (100) beat classes (10) beat elements (1). Chain selectors to increase specificity.

/* Specificity = 1 (element) */
p { color: black; }

/* Specificity = 10 (class) - WINS */
.text { color: blue; }

/* Specificity = 100 (ID) - WINS OVER CLASS */
#intro { color: red; }

/* Specificity = 11 (1 element + 1 class) */
p.highlight { color: yellow; }

/* Specificity = 101 (1 ID + 1 element) - WINS */
#header p { color: green; }

/* Avoid: Specificity = 1000 (inline) - NEVER USE */
<p style="color: purple;">Don't do this</p>

Try it - Specificity in action

Element selector (1)

Class selector (10)

ID selector (100)

Element + Class (11)

CSS applies the most specific rule. Higher specificity wins.

Selector Specificity Chart

Selector Specificity Example
Element 1 p, div
Class 10 .button, [type="text"]
ID 100 #header
Inline Style 1000 style="color: red;"
!important Highest color: red !important;
Element + Class 11 p.highlight
Descendant Chain Sum of all .header .nav .link = 30

Summary

  • Combinators target elements based on relationships: >, +, ~.
  • Attribute selectors match elements by attributes: [attr], [attr="value"].
  • ::before and ::after add content and styling to elements.
  • Specificity determines which CSS rule applies when conflicts occur.
  • Chain selectors to increase specificity when needed.
  • Avoid !important - it breaks cascading and causes issues.
  • Combine techniques for powerful, precise targeting.