Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS selector that applies only to the descendants with closest depth

I have two class HoverShow and HoverHidden.
HoverHidden elements should have at least one HoverShow ancestor and only be displayed when the closest HoverShow ancestor is hovered.

.HoverHidden 
{
    display: none;
}

.HoverShow:hover .HoverHidden
{
    display: initial;
}

<div class="HoverShow">
    <div>
        Hover here to see message!
        <div class="HoverHidden">
            message!
        </div>
    </div>
</div>

The above works just fine.

But things get more complicated when HoverHidden has several HoverShow ancestors.

<div class="HoverShow">
    <div>
        Hover here to see message!
        <div class="HoverHidden">
            message!
            <div class="HoverShow">
                Now hover here to see another message!
                <div class="HoverHidden">
                    another message!
                    <br />
                    Hey, wait... you shouldn't see that yet!
                </div>
            </div>
        </div>
    </div>
</div>

How can I adapt my CSS to make it work?

Please note that I have no rule concerning the depth of a HoverHidden under its closest HoverShow ancestor.

like image 708
Serge Avatar asked Jan 31 '14 08:01

Serge


People also ask

What is a descendant selector in CSS?

The CSS descendant selector allows you to target an element that is a descendant of an element type. The element does not have to be a direct child, but rather any descendant down the line.

What is descendant combinator selector?

The descendant combinator — typically represented by a single space (" ") character — combines two selectors such that elements matched by the second selector are selected if they have an ancestor (parent, parent's parent, parent's parent's parent, etc.) element matching the first selector.

What are the 3 different kinds of selectors in CSS?

Simple selectors (select elements based on name, id, class) Combinator selectors (select elements based on a specific relationship between them) Pseudo-class selectors (select elements based on a certain state)


1 Answers

Your biggest issue with pure css is your final caveat of "Please note that I have no rule concerning the depth of a HoverHidden under its closest HoverShow ancestor." If it truly could be theoretically infinite, then no pure css solution exists. If there is some reasonable, practical limit for the level of nesting between HoverShow and HoverHidden, then you could do css like so (this allows up to 3 intermediate levels of nesting, so you can see how impractical this could get with too many more levels):

.HoverShow:hover > .HoverHidden,
.HoverShow:hover > :not(.HoverShow) > .HoverHidden,
.HoverShow:hover > :not(.HoverShow) > :not(.HoverShow) > .HoverHidden,
.HoverShow:hover > :not(.HoverShow) > :not(.HoverShow) > :not(.HoverShow) > .HoverHidden
{
    display: initial;
}

See a fiddle example.

Please Note

A simple descendent .HoverShow:hover :not(.HoverShow) .HoverHidden will not work, as it will have positive hits on any descendent element that has no .HoverShow class, so as this fiddle shows, the third group does show on the hover of the second group because of the intervening nesting creating elements that do "not" have the .HoverShow class on them.

like image 124
ScottS Avatar answered Oct 12 '22 01:10

ScottS