DEV3 Technologies home

DEV3 Developer Forum

How do I use the CSS :has() selector and native nesting? Can CSS select a parent now?

dev3 ·

I want to style a card differently when it contains an image, or highlight a form row when its checkbox is checked, without JavaScript. I read that :has() is the parent selector. How does it work and is it safe to use?

#css#has#nesting#selectors

0

1 reply

dev3 · Accepted answer

Yes, :has() is the relational (parent) selector

It is supported in all current evergreen browsers (Chrome 105+, Safari 15.4+, Firefox 121+). It selects an element based on its descendants or following siblings.

/* card that contains an image gets a different layout */
.card:has(img) { display: grid; grid-template-columns: 120px 1fr; }

/* highlight the row whose checkbox is checked */
.row:has(input[type="checkbox"]:checked) { background: #eff6ff; }

/* field with an invalid input */
.field:has(input:user-invalid) label { color: #b91c1c; }

/* previous sibling trick: label before a focused input */
label:has(+ input:focus) { color: #2563eb; }

/* style the whole page when a modal is open */
body:has(dialog[open]) { overflow: hidden; }

Quantity queries

.list:has(> li:nth-child(4)) { columns: 2; }  /* at least 4 items */

Native nesting

CSS nesting (no Sass needed) works in all current browsers:

.card {
  padding: 1rem;
  border-radius: 8px;

  &:hover { box-shadow: 0 4px 16px rgb(0 0 0 / .12); }
  & h2 { font-size: 1.25rem; }
  .compact & { padding: .5rem; }
  @media (min-width: 768px) { padding: 1.5rem; }
}

Relaxed nesting means you can nest type selectors without & in current versions, but keeping & is clearer and compatible with older engines.

Tailwind

has-[img]:grid, has-[:checked]:bg-blue-50, and for state of a sibling use peer/group variants. Tailwind 4 also provides in-* and not-* variants.

Pitfalls

  • :has() cannot be nested inside another :has().
  • Heavy selectors like html:has(...) with expensive descendants can cost on huge DOMs; scope to a component.
  • Provide a sensible default when unsupported: the base style should work without :has, and the rule enhances it.
0

Your reply

Every post is reviewed by DEV3 before it appears. Usually reviewed within 24 hours.

Markdown supported. Use ``` for code blocks. Images are not allowed.