CodeBlanks Logo Icon CodeBlanks

:where and :has

CSS course · Intermediate · Lesson 27/98

Learn :where and :has pseudo-classes.

The :where pseudo-class

The :where() function groups the selector list inside it and behaves as a single selector. Its key trait is zero specificity contribution.

Write :where(h1, h2, h3) { color: navy; } and all three headings turn navy; but because specificity is zero, any class selector easily overrides it. This makes :where ideal for a safe base in a theme skeleton.

The :has pseudo-class

The :has() function looks at an element's content. If the element has a descendant matching the selector inside, the parent is matched. This is why it is also called the parent selector.

Write a:has(> img) and you select every a tag that directly contains an image. What used to require JavaScript is now a single line of CSS. It is perfect for styling image links.

Real use: the card parent

The power of :has is styling a parent based on its content. Add a border when a card holds an image, skip it otherwise — one line does it.

Write .card:has(img) { padding: 0; } and any card that contains an image gets zero padding; the image reaches the card's edges. This used to require JavaScript.

Exercise Make image links block-level

Write an a:has(> img) selector and add display: block inside. Links that directly contain an image will become block-level.

Show example solution
/* style image links */
a:has(> img) {
  display: block;
}

Test yourself

  1. What color does the h1 get?

    :where(h1, h2) {
      color: navy;
    }
    h1 {
      color: red;
    }
    • red — the h1 selector wins
    • navy — :where takes effect
    • The browser throws an error
    • The color does not change
    Show answer

    red — the h1 selector wins — Correct. :where has zero specificity, so the plain h1 selector wins and the color is red.

  2. Select a link that contains an image

    a____ {
      display: block;
    }
    Show answer
    a:has(img) {
      display: block;
    }
  3. Match each pseudo-class to its job

    :where(h1, h2)
    Zero-specificity grouping
    :has(> img)
    Parent holding an image
    :where(.btn)
    Easily overridden base
    :has(.badge)
    Element holding a badge

All lessons in Intermediate