Is there a `pointer-events:hoverOnly` or similar in CSS?

HtmlCssPointer Events

Html Problem Overview


Just been playing about with pointer-events property in CSS.

I have a div that I want to be invisible to all mouse events, except for :hover.

So all click commands go through the div to the one below it, but the div can report whether the mouse is above it or not still.

Can anyone tell me if this can be done?

HTML:

<div class="layer" style="z-index:20; pointer-events:none;">Top layer</div>
<div class="layer" style="z-index:10;">Bottom layer</div>

CSS:

.layer {
    position:absolute;
    top:0px;
    left:0px;
    height:400px;
    width:400px;
}

Html Solutions


Solution 1 - Html

Hover only. It is very easy. No JS... Prevent link default action too.

a:hover {
	color: red;
}
a:active {
	pointer-events: none;
}

<a href="www.google.com">Link here</a>

Edit: supported in IE 11 and above http://caniuse.com/#search=pointer-events

Solution 2 - Html

"Stealing" Xanco's answer but without that ugly, ugly jQuery.

Snippet: Notice DIVs are in reverse order

.layer {
  position: absolute;
  top: 0px;
  left: 0px;
  height: 400px;
  width: 400px;
}

#bottomlayer {
  z-index: 10
}

#toplayer {
  z-index: 20;
  pointer-events: none;
  background-color: white;
  display: none
}

#bottomlayer:hover~#toplayer {
  display: block
}

<div id="bottomlayer" class="layer">Bottom layer</div>
<div id="toplayer" class="layer">Top layer</div>

Solution 3 - Html

I don't think it's possible to achieve your aims in CSS alone. However, as other contributors have mentioned, it's easy enough to do in JQuery. Here's how I've done it:

HTML

<div
  id="toplayer"
  class="layer"
  style="
    z-index: 20;
    pointer-events: none;
    background-color: white;
    display: none;
  "
>
  Top layer
</div>
<div id="bottomlayer" class="layer" style="z-index: 10">Bottom layer</div>

CSS (unchanged)

.layer {
    position:absolute;
    top:0px;
    left:0px;
    height:400px;
    width:400px;
}

JQuery

$(document).ready(function(){
    $("#bottomlayer").hover(
        function() {
            $("#toplayer").css("display", "block");
        },
        function() {
            $("#toplayer").css("display", "none");
        }
    );
});

Here's the JSFiddle: http://www.jsfiddle.net/ReZ9M

Solution 4 - Html

You can also detect hover on different element and apply styles to it's child, or using other css selectors like adjacent children, etc.

It depends on your case though.

On parent element hover. I did this:

.child {
    pointer-events: none;
    background-color: white;
}

.parent:hover > .child {
    background-color: black;
}

Solution 5 - Html

Pure CSS solution to your request (the opacity property is there just to illustrate the need for the transitions):

.hoverOnly:hover {
    pointer-events: none;
    opacity: 0.1;
    transition-delay: 0s;
}
.hoverOnly {
    transition: ,5s all;
    opacity: 0.75;
    transition-delay: 2s;
}

What it does:

When the mouse enters the box, it triggers the :hover state. However, in that state, the pointer-events are disabled.

But if you do not set the transitions timers, the div will cancel the hover state when the mouse moves; the hover state will flicker while the mouse is moving inside the element. You can perceive this by using the code above with the opacity properties.

Setting a delay to the transition out of the hover state fixes it. The 2s value can be tweaked to suit your needs.

Credits to transitions tweak: patad on this answer.

Solution 6 - Html

Just pure css, doesn't need jquery:

div:hover {pointer-events: none}
div {pointer-events: auto}

Solution 7 - Html

I use the :hover pseudo-element of an equal-sized parent/container to simulate a hover over my overlay div, then set the overlay's pointer-events to none to pass through clicks to elements below.

<div id="container">
  <div id="overlay"></div>
  <button id="woohoo-button">
    Click Me
  </button>
</div>

#container {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  background-color: green;
  width: 300px;
  height: 300px;
}

#overlay {
  background-color: black;
  width: 100%;
  height: 100%;
  opacity: 0;
  z-index: 1;
  /* Pass through clicks */
  pointer-events: none;
}


/* 
   Set overlay hover style based on
   :hover pseudo-element of its  
   container
*/
#container:hover #overlay {
  opacity: 0.5;
}

#woohoo-button {
  position: absolute;
  width: 100px;
  height: 100px;
  background-color: red;
}

let button = document.getElementById('woohoo-button');
button.onclick = () => console.log('woohoo!');

let overlay = document.getElementById('overlay');
overlay.onclick = () => console.log(`Better change my pointer-events property back to 'none'`);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJimmeryView Question on Stackoverflow
Solution 1 - HtmlСвободен РобView Answer on Stackoverflow
Solution 2 - HtmlNiet the Dark AbsolView Answer on Stackoverflow
Solution 3 - HtmlXancoView Answer on Stackoverflow
Solution 4 - HtmlmaciejmatuView Answer on Stackoverflow
Solution 5 - HtmlMindwinView Answer on Stackoverflow
Solution 6 - HtmlBariq DharmawanView Answer on Stackoverflow
Solution 7 - HtmlJeremy SabathView Answer on Stackoverflow