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

4

15

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.

Musketry answered 23/11, 2012 at 6:2 Comment(6)
If .aa .cc is too general because you don't want to match .cc elements that are more distant descendants of .aa elements, then I think the .aa > .bb > .cc, .aa > .cc selector you already mentioned is best.Mania
In standard CSS there is no other way.Depositary
Are .bb and .cc the only two possible children of .aa?Depositary
@Depositary No, .aa has other children too. (What did you have in mind, if the answer had been yes?)Musketry
I would have suggested .aa > .cc, .aa > * > .cc. Doesn't do much, but it would allow you to skip typing .bb...Depositary
Any updates? I've got the same questionHumboldt
W
15

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 :)

Wolenik answered 27/11, 2012 at 15:3 Comment(1)
I almost thought it was not possible! Thanks :-)Musketry
E
1

Wouldn't .aa > .cc, .aa > .bb > .cc {} work? Or did I misunderstand your question?
This selects only the .cc that are direct .aa children and the .cc that are .bb children (children of .aa) as well.

Efferent answered 23/11, 2012 at 6:11 Comment(1)
Yes it'd work, but I was wondering if there's a shorter alternative.Musketry
B
1

if you want use your option, by the way is very interesting, you can use a form most correct:

>.aa (>.bb)? >.cc { ... }

but the form correct would:

.aa .cc { ... }

into stylus:

.aa   
  .cc

thats all.

Bullock answered 27/6, 2013 at 15:55 Comment(1)
Thanks for your answer, and I don't really understand it. I don't realize what you mean with "you can use a form most correct" Are you saying that .aa (>.bb)? >.cc { ... } is valid CSS? (I don't think it is)Musketry
V
0

I used :has() solution, for giving selector reinforcement when available

//adds .specific-ancestor-class as more specific selector, when available as ancestor, otherwise select inner with less specificity
*:has(.specific-ancestor-class, *){
    .inner {
        //style...
    }
}
Vosges answered 2/12, 2020 at 10:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.