Optional child selector, with CSS/Stylus/LESS: .aa > .bb? > .cc

KajMagnus picture KajMagnus · Nov 23, 2012 · Viewed 6.9k times · Source

Consider this HTML with CSS classes aa, bb and cc:

<div class='aa'>
<div class='bb'>
<div class='cc'>
</div>
</div>
</div>

I can select the class=cc tag like so: .aa > .bb > .cc. However, in my case, sometimes the .bb tag is absent, that is, the HTML looks like so:

<div class='aa'>
<div class='cc'>
</div>
</div>

Thererfore, to select all .cc close to an .aa, I'd need to specify two CSS paths:

.aa > .bb > .cc,
.aa > .cc { .... }

This works, but, is there no shorter way? Something similar to this:

.aa > (.bb >)? .cc { ... }   /* ? means "optional" */

with CSS or something like Stylus or LESS?

Motivation: In the real world, "aa" and "bb" and "cc" are somewhat longer names, and there's more stuff before and after the "aa" and "cc", and it'd be nice to not need to duplicate that stuff.

Please note: In my case, this won't work: .aa .cc because that'd match too many .ccs elsewhere on the page. The .ccs need to be either immediately below the .aa, or below .aa > .bb.

Answer

kizu picture kizu · Nov 27, 2012

For Stylus and Sass you could do this (live example for Sass):

.aa
  > .bb, &
    > .cc
      width: 10px

I couldn't find a way to do so in a one-liner for Sass, but for Less/Stylus/Scss you could do also this (live examples for Scss, for Less) :

.aa { > .bb, & { > .cc {
  width: 10px
}}}

This is not that pretty also, but still better than nothing :)