Writing clean CSS often means writing fewer, more powerful selectors. Advanced selectors let you style elements based on their attributes, state, or position in the document tree without adding extra classes.

Attribute Selectors

These select elements based on the presence or value of an attribute.

  • [href]: Selects any <a> tag with an href attribute.
  • [target="_blank"]: Selects <a> tags that open in a new tab.
  • [class^="icon-"]: Selects elements whose class starts with "icon-".
  • [href$=".pdf"]: Selects links whose href ends with ".pdf".
  • [class*="btn-"]: Selects elements whose class contains "btn-".

Code Snippet: Styling Links Based on File Type

CSS


/* Style links to PDF files */
a[href$=".pdf"]::after {
  content: ' (PDF)';
  color: #e74c3c;
  font-size: 0.8em;
}

/* Style links that open in a new tab */
a[target="_blank"] {
  background: url('/icons/external-link.svg') no-repeat right center;
  padding-right: 18px;
}

Pseudo-classes and Pseudo-elements

  • Pseudo-classes (:) select elements based on their state or a characteristic. Examples include :hover, :focus, :nth-child(n), and :not().
  • Pseudo-elements (::) select and style a specific part of an element. Examples include ::before, ::after, ::first-line, and ::selection.

Code Snippet: Styling a List

CSS


/* Style every odd list item */
li:nth-child(odd) {
  background-color: #f2f2f2;
}

/* Add a decorative bullet point before each list item */
li::before {
  content: 'β†’ ';
  color: #3498db;
  margin-right: 8px;
}

Combinators

Combinators define the relationship between selectors.

  • Descendant (space): article p selects all <p> elements anywhere inside an <article>.
  • Child >: ul > li selects only <li> elements that are direct children of a <ul>.
  • Adjacent Sibling +: h2 + p selects the first <p> that immediately follows an <h2>.
  • General Sibling ~: h2 ~ p selects all <p> elements that follow an <h2> and share the same parent.

Code Snippet: Using the Adjacent Sibling Combinator

CSS


/* Add some top margin to a paragraph that directly follows a heading */
h2 + p {
  margin-top: 0;
  font-style: italic;
  color: #555;
}