CSS :where() Function

Contribute and help us stay up-to-date. Edit this page on GitHub.

This article demonstrates how to use the CSS :where() function within CSS Cascading Style Sheets. Included in this guide are code, definitions, and examples.

The :where() function is a functional pseudo-class that takes a list of selectors as its argument and applies the styles to the selected HTML elements in the list. It allows developers to specify conditions that must be met before a particular style is applied to an element.

The syntax for the where() function is as follows:

selector where(condition) {
  /* Styles to apply */
}

:where( <complex-selector-list> )

In this syntax, the selector is any valid CSS selector, and condition which is a boolean expression that must be true for the styles to be applied. If the condition is false, the styles will be ignored.

The parameter of the :where() function is a <complex-selector-list> data type and should be replaced with an example value such as: :where(:not(:hover)).

The examples below use selectors and selector list values for the parameter of the :where() function.

:where(:not(:hover))
:where(ol, ul, menu:unsupported)
:where(section, aside, footer) a
:where(header, main, footer) a:hover
:where(header, footer) > p
:where(button, a)
:where(.light-theme, .bright-theme)
:where(ol[class])
:where(:valid, :unsupported)
:where(#section) h2

You can apply the :where() function to any element by using CSS selectors and adding styles.

:where(ol, ul) :where(ol, ul) ol {
    list-style-type: lower-greek;
    color: green;
}

:where(section) a:hover {
  color: blue;
  text-decoration: underline;
}

article :where(footer, aside) > p {
  color: orange;
}

:where(button, a) {
  color: purple;
}

main :where(h1, h2, h3) {
  color: orange;
}

For example, suppose we want to apply a different background color to paragraphs that contain the word “important”. We could use the following CSS:

p where(:contains("important")) {
  background-color: yellow;
}

In this CSS, the where() function is used to apply the background-color property only to paragraphs that contain the word important. The :contains() pseudo-class is used to match any element that contains the specified text.

Applying styles to the first child element that meets a condition:

div where(p:first-of-type) {
  /* styles to apply */
}

In this example, the where() function is used to apply styles to the first paragraph element inside a div element.

Applying styles to an element that has a specific attribute:

a where([target="_blank"]) {
  /* styles to apply */
}

In this example, the where() function is used to apply styles to an anchor element that has the attribute target set to _blank.

  • Overriding Styles:where() is helpful for creating filters in a selector while keeping associate selectors easy to override.
  • Shorting Selector Lists:where() can shorten CSS style selectors by reducing redundancy and is very useful in shortening CSS code.
header a:hover,
main a:hover,
aside:hover,
footer a:hover {
  color: blue;
  text-decoration: underline;
}

The above CSS selectors can be reduced by using the :where() function because the selectors can be turned into a list. The example below reduced the characters from 100 to 89, an 11% reduction.

:where(header, main, aside, footer) a:hover {
  color: blue;
  text-decoration: underline;
}

Using the :where() function gives us the advantage of creating shorter and more readily understandable lists.

CSS :where() function is similar to :is() syntax and functionality. However, the difference between :is() and :where() is that :where() is their specificity.

The CSS :where() function always has a specificity of zero. This means that the :where() pseudo-class or its argument list does not contribute to the specificity of the selector.

An example of specificity failing.

a:not(:hover) {
  text-decoration: none;
  color: blue;
}

nav a {
  /* Has no effect */
  text-decoration: underline;
  color: orange;
}

However, by using :where() you can explicitly declare selector intent:

a:where(:not(:hover)) {
  text-decoration: none;

  color: blue;
}

nav a {
  /* Works now! */
  text-decoration: underline;

  color: orange;
}

The :where() function is forgiving in that each selector within the comma-separated list :where(x, y, z) is ignored if it is an invalid selector. With :where() being forgiving, this means invalid selectors within the pseudo-class don’t disable the entire selector like they normally do.

Syntactically the comma list is a data value which is equivalent to <any-value>? The browser then parses the forgiving selector list into valid selectors to obtain its actual value.

Below, the totally:fake selector is ignored while the heading selector isn’t.

:where(<forgiving-selector-list> | <any-value>?) {
  /* Some element */
}

/* Invalid "totally:fake is ignored */
:where(heading, totally:fake) {
  /* will still select heading */
}

When using :where(), we can place it at the beginning, middle, or end of a selector. This allows us to use the function to combine selectors in different ways.

Here is an example of multiple styles and selectors.

/* first list */
header a:hover,
section: a:hover,
main a:hover,
footer a:hover {
  color: green;
  text-decoration: underline;
}

/* second list */
article header > p,
article section > p,
article footer > p {
  color: blue;
}

/* third list */
.light-theme button,
.light-theme a {
  color: black;
}

In the first CSS style block, we set the green and underline values to be applied to the header, section, main, and footer elements whenever the link element is hovered.

In the second list, we specify that the article’s header, section, and foote paragraph elements should be styled with blue text.

The last list uses the .light-theme class to apply styles to the link and button elements. The class contains properties to set the text color to black for those elements.

Now we can use the :where() function to reduce the CSS.

/* first list */
/* at the beginning */
:where(header, section, main, footer) a:hover {
  color: green;
  text-decoration: underline;
}

/* second list */
/* in the middle */
article :where(header, section, footer) > p {
  color: blue;
}

/* third list */
/* at the end */
.light-theme :where(button, a) {
  color: black;
}

We replaced each selector group with a :where() function. This resulted in fewer selectors, as the selector’s redundant parts were removed.

Using another example, we can use the :where() function to target different links within HTML elements such as the header, sections, and footers.

Targeting Link Elements With CSS where()
Targeting Link Elements With CSS where()
<article>
  <h2>:where()-styled links</h2>
  <header class="where-styling">
    <p>
      Here is my header content. This
      <a href="https://appcode.app">contains a link</a>.
    </p>
  </header>

  <section class="where-styling">
    <p>
      Here is my section content. This
      <a href="https://appcode.app">also contains a link</a>.
    </p>
  </section>

  <aside class="where-styling">
    <p>
      Here is my aside content. This
      <a href="https://appcode.app">also contains another link</a>.
    </p>
  </aside>

  <footer class="where-styling">
    <p>
      This is my footer, also containing
      <a href="https://appcode.app">a link</a>.
    </p>
  </footer>
</article>
html {
  font-family: sans-serif;
  font-size: 150%;
  text-align: center;
  height: 100%;
  margin: 0;
  -webkit-box-align: center !important;
  -ms-flex-align: center !important;
  align-items: center !important;
  -webkit-box-pack: center !important;
  -ms-flex-pack: center !important;
  justify-content: center !important;
  display: -webkit-box !important;
  display: -ms-flexbox !important;
  display: flex !important;
}

:where(header.where-styling) a {
  color: blue;
}

:where(section.where-styling) a {
  color: green;
}

:where(aside.where-styling, footer.where-styling) a {
  color: orange;
}

The last CSS selector uses a :where() to override the last link element color from its default orange.

Below, we show how to use the :where() function to style and target different levels of unordered and ordered lists by supplying selectors in the parameter :where().

Using The CSS where() Function
Using The CSS where() Function
<ol>
  <li>Shapes</li>
  <ul>
    <li>Square</li>
    <li>
      <ul>
        <li>Color</li>
        <li>Size</li>
        <li>
          <ol>
            <li>X</li>
            <li>Y</li>
            <li>Z</li>
          </ol>
        </li>
        <li>Weight</li>
      </ul>
    </li>
    <li>Circle</li>
    <li>
      <ol>
        <li>Color</li>
        <li>Weight</li>
      </ol>
    </li>
  </ul>
</ol>
html,
body {
  height: 100%;
  margin: 0;
  -webkit-box-align: center !important;
  -ms-flex-align: center !important;
  align-items: center !important;
  -webkit-box-pack: center !important;
  -ms-flex-pack: center !important;
  justify-content: center !important;
  display: -webkit-box !important;
  display: -ms-flexbox !important;
  display: flex !important;
  font-size: 18px;
}

ol {
  list-style-type: number;
  color: darkblue;
}

/* Not applied to ol, because of lower specificity */
:where(ol, ul, menu:unsupported) :where(ol, ul) {
  color: green;
}

:where(ol, ul ul) :where(ol, ul ul) ol {
  list-style-type: lower-greek;
  color: brown;
}

:where(ol, ul ul) :where(ol, ul ul) {
  list-style-type: lower-alpha;
  color: #871f78;
}

W3C CSS Selectors Level 4
#zero-matches