0

I have to apply a style to a class .my-icon (3rd level element- Image) on hover of h1,h2 or h3(2nd level element - heading) that are in a .container (1st level element - Div), following is the code

.container > h1:hover > .my-icon,
.container > h2:hover > .my-icon,
.container > h3:hover > .my-icon
 {
    display:inline;
}

Is there any simpler (or compact) way of doing it? some thing like

.container > (h1|h2|h3):hover > .myicon {

}

or may be in following way

.container > (h1:hover|h2:hover|h3:hover) > .myicon {

    }

or any other compact way?

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
PHP Avenger
  • 1,744
  • 6
  • 37
  • 66
  • 2
    use a class for the headings then you can do `.heading-class:hover .my-icon { display:inline; }` - that's the whole point of classes – Pete Dec 05 '14 at 12:14

1 Answers1

2

This will be made possible with the upcoming :matches() selector:

.container > :matches(h1, h2, h3):hover > .myicon {
    display: inline;
}

While this is currently implemented internally as :any() in multiple browsers, it is implemented with prefixes, rendering it pointless to use as it forces you to bloat your code even further in order to avoid the rule that unrecognized selectors must invalidate the entire ruleset:

/* 
 * Why do this when you can just compact your three selectors
 * into a single rule as you're already doing?
 */

.container > :-moz-any(h1, h2, h3):hover > .myicon {
    display: inline;
}

.container > :-webkit-any(h1, h2, h3):hover > .myicon {
    display: inline;
}

.container > :matches(h1, h2, h3):hover > .myicon {
    display: inline;
}

In the meantime, if you do not have access to a preprocessor that supports nesting of rules, and you cannot change your markup, you will need to stick with what you have.

Alternatively, you could also remove parts of your selector based on assumptions of your markup. For example, if .myicon will only ever appear in .container > :matches(h1, h2, h3) anyway, then you may not need to look for :matches(h1, h2, h3) — you can just do this instead:

.container > *:hover > .myicon {
    display: inline;
}

(The * is for illustration but not necessary; :hover by itself is valid CSS, just as .container and .myicon are.)

Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • In webkit it will be `.container > :-webkit-any(h1, h2, h3):hover > .my-icon { ... }` – dfsq Dec 05 '14 at 12:15
  • Yeah but like I said, it's pointless to use due to the prefixes. I updated my answer with an example - I think this is one of the better scenarios to demonstrate as the selector in question has three parts, and when you add `:matches()` into the mix you'll also end up with three separate rules. You can then really see the bloat once you're forced to repeat your declaration blocks. – BoltClock Dec 05 '14 at 12:28