# CSS `:is()` and `:where()`

The `:is()` and `:where()` pseudo-class functions allow you to group selectors, reducing repetition and making CSS more readable. They function similarly but have one key difference regarding specificity.

## 1. Grouping Selectors

Instead of writing the same selector multiple times with different variations, you can group them.

**Without `:is()`:**
```css
header p,
main p,
footer p {
  color: red;
}
```

**With `:is()`:**
```css
:is(header, main, footer) p {
  color: red;
}
```

This is equivalent to the expanded version above.

## 2. The Difference: Specificity

The main difference between `:is()` and `:where()` is how they affect the specificity of the selector.

### `:is()`
The specificity of the `:is()` pseudo-class is equal to the **most specific selector** in its argument list.

```css
/* Specificity: (0, 1, 0, 1) - ID wins */
:is(#id, .class, tag) {
  color: blue;
}
```
Even if the element matches `.class`, the rule carries the weight of `#id`.

### `:where()`
The specificity of the `:where()` pseudo-class is always **zero** `(0, 0, 0, 0)`. It does not add any weight to the selector.

```css
/* Specificity: (0, 0, 0, 0) */
:where(#id, .class, tag) {
  color: green;
}
```

## 3. Use Cases

### Simplifying Selectors
Both are great for reducing code duplication.

```css
/* Complex selector */
article h1, article h2, article h3,
section h1, section h2, section h3 {
  margin-bottom: 1em;
}

/* Simplified */
:is(article, section) :is(h1, h2, h3) {
  margin-bottom: 1em;
}
```

### Resetting Styles (`:where`)
Because `:where()` has zero specificity, it is perfect for CSS resets or default library styles. It allows developers to easily override the styles without needing high specificity or `!important`.

```css
/* Library default */
:where(.btn) {
  background-color: gray; /* Specificity 0 */
}

/* User override */
.btn {
  background-color: blue; /* Specificity 0, 1, 0 - Wins! */
}
```

### Forgiving Selector Lists
Both `:is()` and `:where()` use a "forgiving selector list". In standard CSS, if one selector in a comma-separated list is invalid, the entire rule is ignored. Inside `:is()` or `:where()`, the invalid selector is ignored, but the valid ones still work.

```css
/* If :unsupported is invalid, the whole rule fails in standard CSS */
:unsupported, h1 { color: red; }

/* With :is(), h1 still gets styled */
:is(:unsupported, h1) { color: red; }
```

[[programming/css/css]]
[[programming/css/selectors]]
[[programming/css/specificity]]