Day 6: the :has() pseudo-class

posted on

It’s time to get me up to speed with modern CSS. There’s so much new in CSS that I know too little about. To change that I’ve started #100DaysOfMoreOrLessModernCSS. Why more or less modern CSS? Because some topics will be about cutting-edge features, while other stuff has been around for quite a while already, but I just have little to no experience with it.


:has() allows you to check whether a parent element contains specific children.

In the following example, each .form-item that contains/has a child with the aria-invalid attribute set to “true” displays text in red color. (currently only in Chrome/Edge 105+ and Safari 15.4+)



<form>
  <div class="form-item">
    <label for="name">Name</label><br>
    <input type="text" id="name" required aria-invalid="true">
  </div>

  <div class="form-item">
    <label for="email">E-Mail</label><br>
    <input type="text" id="email">
  </div>
</form>

.form-item {
  --color: #000;

  /* The default color is #000 */
  color: var(--color);
}

input {
  /* The default border-color is #000 */
  border: 1px solid var(--color);
}

/* If the .form-item contains an element with [aria-invalid="true"], 
the text and border color changes to #F00 */
.form-item:has([aria-invalid="true"]) {
  --color: #F00;
}

See on CodePen

Further reading

Overview: 100 Days Of More Or Less Modern CSS