The :where()
pseudo-class is very similar to :is()
in that it takes a selector list as an argument and matches any element that can be selected by one of the selectors in that list. The key difference is that :where()
always has a specificity of 0. This makes it ideal for creating broad, overridable styles.
Example 1: Zero Specificity
/* This rule has zero specificity and can be easily overridden */
:where(h1, h2, h3) {
color: gray;
}
h2 {
color: blue; /* This will override the :where() rule */
}
Explanation
Even though the h2
selector is simpler, it will override the color set by :where()
because :where()
has no specificity. This is the primary advantage of using :where()
.
Example 2: Theming Defaults
/* Set default link colors with zero specificity */
:where(a:link, a:visited) {
color: #007bff;
}
Explanation
This is a great way to set a default style for links that can be easily customized later without needing more complex selectors. Any other style rule for links will override this one.
Example 3: Reset Styles
/* A simple CSS reset with no specificity */
:where(body, h1, h2, p, ul, ol) {
margin: 0;
padding: 0;
}
Explanation
Using :where()
in a CSS reset is a modern best practice. It allows developers to apply baseline styles that can be effortlessly overridden by their own component-specific styles without specificity conflicts.
Example 4: Form Element Defaults
/* Default styling for form buttons */
:where(button, input[type="submit"]) {
font-family: inherit;
font-size: 100%;
}
Explanation
This rule provides default typographic properties for buttons and submit inputs. Since it has zero specificity, you can easily style a specific button differently with a simple class or ID selector.
Example 5: Overridable Grid Layouts
/* A default grid layout that can be easily changed */
:where(.grid-container) {
display: grid;
gap: 1em;
}
Explanation
Here, a base grid layout is defined using :where()
. If you need a different grid layout for a specific container, you can apply a class and define new grid properties, and they will apply without any specificity issues.
Example 6: Unstyled List
/* Creates an unstyled list that can be styled later */
:where(ul.unstyled, ol.unstyled) {
list-style: none;
padding-left: 0;
}
Explanation
This creates a utility class unstyled
for lists. Because it uses :where()
, you can easily apply other list styles to elements with this class, for instance, to add back padding for a specific nested list.
Example 7: Broad Component Styles
/* Default styles for all components with a 'card' class */
:where([class*="card"]) {
border: 1px solid #ddd;
border-radius: 8px;
}
Explanation
This rule applies a default border and border-radius to any element whose class attribute contains the word "card". The zero specificity of :where()
ensures that more specific styling for different card variations will be applied without hassle.