Using only CSS, show div on hover over another element

I would like to show a div when someone hovers over an <a> element, but I would like to do this in CSS and not JavaScript. Do you know how this can be achieved?


Solution 1:

You can do something like this:

div {
    display: none;
}
    
a:hover + div {
    display: block;
}
<a>Hover over me!</a>
<div>Stuff shown on hover</div>

This uses the adjacent sibling selector, and is the basis of the suckerfish dropdown menu.

HTML5 allows anchor elements to wrap almost anything, so in that case the div element can be made a child of the anchor. Otherwise the principle is the same - use the :hover pseudo-class to change the display property of another element.

Solution 2:

.showme {
  display: none;
}

.showhim:hover .showme {
  display: block;
}
<div class="showhim">HOVER ME
  <div class="showme">hai</div>
</div>

jsfiddle

Since this answer is popular I think a small explanation is needed. Using this method when you hover on the internal element, it wont disappear. Because the .showme is inside .showhim it will not disappear when you move your mouse between the two lines of text (or whatever it is).

These are example of quirqs you need to take care of when implementing such behavior.

It all depends what you need this for. This method is better for a menu style scenario, while Yi Jiang's is better for tooltips.

Solution 3:

I found using opacity is better, it allows you to add css3 transitions to make a nice finished hover effect. The transitions will just be dropped by older IE browsers, so it degrades gracefully to.

#stuff {
    opacity: 0.0;
    -webkit-transition: all 500ms ease-in-out;
    -moz-transition: all 500ms ease-in-out;
    -ms-transition: all 500ms ease-in-out;
    -o-transition: all 500ms ease-in-out;
    transition: all 500ms ease-in-out;
}
#hover {
    width:80px;
    height:20px;
    background-color:green;
    margin-bottom:15px;
}
#hover:hover + #stuff {
    opacity: 1.0;
}
<div id="hover">Hover</div>
<div id="stuff">stuff</div>

Solution 4:

I'm by know means an expert, but I'm incredibly proud of myself for having worked something out about this code. If you do:

div {
    display: none;
}

a:hover > div {
    display: block;
} 

(Note the '>') You can contain the whole thing in an a tag, then, as long as your trigger (which can be in it's own div, or straight up in the a tag, or anything you want) is physically touching the revealed div, you can move your mouse from one to the other.

Maybe this isn't useful for a great deal, but I had to set my revealed div to overflow: auto, so sometimes it had scroll bars, which couldn't be used as soon as you move away from the div.

In fact, after finally working out how to make the revealed div, (although it is now a child of the trigger, not a sibling), sit behind the trigger, in terms of z-index, (with a little help from this page: How to get a parent element to appear above child) you don't even have to roll over the revealed div to scroll it, just stay hovering over the trigger and use your wheel, or whatever.

My revealed div covers most of the page, so this technique makes it a lot more permanent, rather than the screen flashing from one state to another with every move of the mouse. It's really intuitive actually, hence why I'm really quite proud of myself.

The only downside is that you can't put links within the whole thing, but you can use the whole thing as one big link.