:where(), :is(), :has(), and :not(), modern pseudo-classes in CSS

,

|

|

|

4 minutes

Did you know that there are some modern pseudo-classes in CSS that can help you select elements based on more complex and dynamic criteria? 🤔
Specifically, using this four – :where(), :is(), :has(), and :not() can make your CSS code more concise and powerful. 💯

Lets explore the details and examples of each one:

  • :where() pseudo-class: This pseudo-class matches elements that match a list of selectors, but it has no effect on the specificity of the selector. This means that it does not increase the weight or importance of the selector, unlike other combinators like +, >, or ~. For example, if you want to style all the paragraphs inside a div with class container, you can write:
:where(div.container) p {
  color: blue;
}

This selector has the same specificity as p, which is very low. This can be useful when you want to avoid overriding other styles that have higher specificity.

  • :is() pseudo-class: This pseudo-class is similar to :where(), but it does affect the specificity of the selector. It matches elements that match any of the selectors in the list. For example, if you want to style all the headings (h1, h2, h3, etc.) inside a section with class main, you can write:
section.main :is(h1, h2, h3, h4, h5, h6) {
  font-weight: bold;
}

This selector has the same specificity as section.main h6, which is higher than p. This can be useful when you want to give more priority to certain styles or when you want to select an element that has a certain child element or elements.

  • :has() pseudo-class: This pseudo-class matches elements that have at least one descendant element that matches the selector in the parentheses. For example, if you want to style all the list items that have a link inside them, you can write:
li:has(a) {
  background-color: yellow;
}

This selector will match any li element that contains an a element, regardless of how deep the a element is nested inside the li element.

:has(), the parent selector


The :has() pseudo-class is called the parent selector because it allows you to select an element that has a certain child element or elements. For example, if you want to select a div that has an img element inside it, you can write:

div:has(img) {
  border: 1px solid black;
}

This selector will match any div element that contains an img element, regardless of how deep the img element is nested inside the div element.

Some simple and complex use cases of the :has() pseudo-class are:

Selecting a list item that has a link with a specific attribute value. For example, if you want to select a li element that has an a element with href=“https://www.google.com”, you can write:

li:has(a[href="https://www.google.com"]) {
  color: blue;
}

Selecting a table row that has a cell with a specific content. For example, if you want to select a tr element that has a td element with the text “Google”, you can write:

tr:has(td:contains("Google")) {
  background-color: yellow;
}

The :contains() selector in CSS selects elements that contain a specified string. The string can be contained directly in the element as text.

Selecting a form that has a checked checkbox or radio button. For example, if you want to select a form element that has an input element with type=“checkbox” or type=“radio” and checked attribute, you can write:

form:has(input[type="checkbox"]:checked, input[type="radio"]:checked) {
  border: 2px solid green;
}

Selecting a section that has a heading with a specific level. For example, if you want to select a section element that has an h1 element, you can write:

section:has(h1) {
  margin-top: 2rem;
}
  • :not() pseudo-class: This pseudo-class matches elements that do not match the selector in the parentheses. This can be useful when you want to exclude some elements from the selection. For example, if you want to style all the paragraphs that are not inside a div with class container, you can write:
p:not(:where(div.container)) {
  color: red;
}

This selector will match any p element that is not a descendant of a div element with class container.

I hope this helps you understand how powerful these pseudo-classes in CSS.


Happy Coding, Cheers 🥂