CSS Sibling Selector w/ Hover
Asked Answered
T

4

11

So here's what I'm trying to do:

I have two icons side by side, and underneath I have two spans that are hidden. When I mouse-over an icon I want the corresponding span to appear.

------------ HTML Part -----------------

<span class="icons"><!--ICONS-->
    <li class="oneLI">one</li>
    <li class="twoLI">two</li>
</span>

<span class="popups">
    <span class="one"></span>
    <span class="two"></span>
</span>

--------------CSS Part --------------

span.popups span.one,span.popups span.two{opacity:0;

span.icons:first-child:hover + span.popups span.one{opacity:1}
span.icons:last-child:hover + span.popups span.two{opacity:1}

Now obviously this doesn't quite work, how would I go about this using only CSS?

http://jsfiddle.net/RLhKK/

Thimbu answered 24/1, 2014 at 19:43 Comment(3)
Basically, you can't, because you can't go "back up" the hierarchy. If you can't change the HTML for some reason, your best bet is JavaScript.Dunlap
possible duplicated topic [link]#18749776Outleap
The list structure above is invalid. List items must be children of a list.Kreegar
B
12

Let me explain your selector first which is

span.icons:first-child:hover + span.popups span.one{opacity:1}

Well, you are trying to select the first-child nested under span.icons and on hover of that you select span.one which is nested inside span.popups but you are going wrong here, you are selecting adjacent span element having .popups which is not adjacent to the span which is nested inside .icons, but in general, your selector is wrong, CSS cannot select the parent, inshort, CSS cannot go back once it enters an element, it cannot move up the hierarchy.

So you cannot do that way, either you need to alter your DOM, and bring all the span elements at the same level, or your hidden span should be at the child level.

And another way to achieve this is by using position, which I won't suggest here.

Also, your markup is invalid, you need to have ul element around li.


Lets alter the DOM and see how we can select

<span class="icons"><!-- Better use div here -->
    <ul>
        <li class="oneLI">one <br /><span class="one">Show Me</span></li>
        <li class="twoLI">two <br /><span class="two">Show me as well</span></li>
    </ul>
</span>

.icons li > span {
    opacity: 0;
}

.icons li:hover > span {
    opacity: 1;
}

Demo


How would I've achieved this?

Demo 2

<div class="icons">
    <span class="hoverme">Hover Me</span>
    <div id="hover1">First</div>
    <span class="hoverme">Hover Me</span>
    <div id="hover2">Second</div>
</div>

.icons > div[id] {
    opacity: 0;
    height: 100px;
    width: 100px;
    background: red;
}

.icons > span {
    display: block;
}

.icons > span:hover + div {
    opacity: 1;
}

You can use display or visibilty property as well, if you do not want to use opacity as they are well suited when you want to transit an element using transition.

Demo 3 (Using transition if you are going for opacity method)

Blouson answered 24/1, 2014 at 19:48 Comment(2)
@GolezTrol Patience patience :) am editing my answerBlouson
How would I do this if I want the "Hover Me's" side by side?Thimbu
D
1

You need the popups corresponding icons to be siblings.

Demo

HTML:

<a href="#" class="icon1">one</a>
<span class="one">one</span>

<a href="#" class="icon2">two</a>    
<span class="two">two</span>

CSS:

span.one, span.two {
    display:none;
}
a.icon1:hover + span.one {
    display:inline;
}
a.icon2:hover + span.two {
    display:inline;
}
Disagreement answered 24/1, 2014 at 19:58 Comment(0)
L
0

You can solve this by putting the popups inside the icons. You can then address them using CSS, and position them somewhere else using absolute positioning:

CSS:

li {
    position: relative;
}

li span {
    display: none;
    position: absolute;
    left: 0; top: 100%;
}

li:hover span {
    display: block;
}

HTML:

<ul class="icons"><!--ICONS-->
    <li class="oneLI">one<span class="one">Popup for one.</span></li>
    <li class="twoLI">two<span class="two">Popup for one.</span></li>
</ul>

Fiddle: http://jsfiddle.net/SK4Np/2/

Louettalough answered 24/1, 2014 at 19:49 Comment(0)
A
0

If you needed to hide block you are hovering upon as I did you can do something like this:

HTML:

<div class="menu-block">
  <div class="menu-block-inner">
    Menu (Hover me)
  </div>
  <div class="menu-expanded">
    <span><a href="#">Menu item1</a></span>
    <span><a href="#">Menu item2</a></span>
  </div>        
</div>

CSS:

.menu-block {
    display: inline-block;
}

.menu-block:hover .menu-block-inner{
    display: none;
}

.menu-block:hover .menu-expanded{
    display: inline-block;
}

.menu-expanded {
    display: none;
}

The idea is to use parent div to trigger the hover event. After event is caught change child div's display/opacity/visibility, etc.

JSFiddle Demo

Assagai answered 11/1, 2016 at 9:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.