Parent Selectors in CSS and Sass

Hero image for Parent Selectors in CSS and Sass. Image by Sergey Zolkin.
Hero image for 'Parent Selectors in CSS and Sass.' Image by Sergey Zolkin.

A longstanding weakness with CSS has been the omission of a parenttype selector. This all boils down to the fact that CSS rules are conventionally matched by the browser from righttoleft, and concomitantly the primary reason that using a flat, nonnested method like BEM is far more performant than a nestedselectors approach.

There is potential in the Selectors Level 4 draft with the (potential) introduction of :has() pseudoclass, which would allow you to target elements that have specific children. For example:

a:has(> img) {  // This would match an anchor with a direct child image}li:has(a.current) {  // This would match an li element where it contained an  // anchor with the class name 'current'}section:not(:has(h1, h2, h3, h4, h5, h6)) {  // This would match a section element where it does not  // contain any heading (h1 - h6)}

This is very exciting, but at the time of writing, not a single browser supports it, so we have to be smart about our CSS, or simply use additional classNames to bridge the gap.

Fortunately, Sass does offer a partial solution in their own parent selector: &.

This special character essentially maps back to the immediate parent selector, allowing you to build up nested selectors like this:

// Sass:.element {  color: lime;  &:hover {    color: purple;    img {      border: 1rem solid yellow;    }  }  & > a {    outline: 0.1rem solid navy;  }}// Generated CSS:.element {  color: lime;}.element:hover {  color: purple;}.element:hover img {  border: 1rem solid yellow;}.element > a {  outline: 0.1rem solid navy;}

In this way you can still target elements based on their parent, by generating accurate nested selectors. It's not ideal, but it is very handy!

The Sass parent selector is also extremely useful for building up BEMtype selectors:

// Sass:.block {  color: lime;  &__element {    color: purple;    &--modifier {      color: navy;    }  }}// Generated CSS:.block {  color: lime;}.block__element {  color: purple;}.block__element--modifier {  color: navy;}

Of course, the more recent significant adoption of CSSinsideJavaScript, combined with JSXtype syntax that allows you to change styles on the fly may well eventually make this obsolete without ever needing the 4th level of CSS selectors...


Categories:

  1. CSS
  2. Development
  3. Front‑End Development
  4. Sass