0

I'm trying to create an element of top my page wich can be hoverred. When hovered I want to change the opacity of the element and allow click through.

The thing is when I add the pointer-events: none to allow the click through, my hover is never triggered, which seems logic after all. I though I would be able to deal with it with javascript, but event mouseover or mouseenter is not compatible with pointer-events: none.

Here is my example with only css: If I add the pointer-events: none; it doesn't work. The element is the red banner, I want to be able to click the buttons underneath while being able to lower the opacity of it.

body {margin:0; padding:0;}
.title {font-weight:bold;margin-right:10px;}
.container {margin: 0 auto;width:80%;position:relative;overflow:hidden;}
.content {height:300px;border: 1px solid #c8c8c8;}
nav {background-color:#efebe0;padding:20px;}
button {padding:10px;background-color:#9ebf00;border: 1px solid #86a200;border-radius:5px;margin: 0 5px 0 5px;}
button.right {float:right;}

.bandeau {
  position: absolute; 
  background: red none repeat scroll 0% 0%; 
  width: 300px; 
  height: 40px; 
  z-index: 2; 
  font-size: 30px; 
  color: white; 
  font-weight: bold; 
  text-align: center; 
  right: -70px; 
  transform: rotate(45deg); 
  top: 60px; 
  display: block;
  transition: 0.2s ease-in-out;
  pointer-events:none;
}

.bandeau:hover {
  opacity: 0.4;
}
<div class="container">
  <nav>
    <span class="title">Dummy Example</span>
    <button>Home</button>
    <button>Pricing</button>
    <button class="right">Contact us</button>
    <button class="right">Log in</button>
  </nav>
  <div class="content"></div>
  <div class="bandeau">
    <span>I will be back !</span>
  </div>
</div>

The other example with javascript :

document.addEventListener('DOMContentLoaded', function() {
  var bandeau = document.getElementById("bandeau");
  bandeau.addEventListener('mouseenter', e => {
    bandeau.style.opacity = '0.4';
    bandeau.style.pointerEvents = 'none';
  });
  bandeau.addEventListener('mouseleave', e => {
    bandeau.style.opacity = '1';
    bandeau.style.pointerEvents = 'auto';
  });
}, false);
body {margin:0; padding:0;}
.title {font-weight:bold;margin-right:10px;}
.container {margin: 0 auto;width:80%;position:relative;overflow:hidden;}
.content {height:300px;border: 1px solid #c8c8c8;}
nav {background-color:#efebe0;padding:20px;}
button {padding:10px;background-color:#9ebf00;border: 1px solid #86a200;border-radius:5px;margin: 0 5px 0 5px;}
button.right {float:right;}

#bandeau {
  position: absolute; 
  background: red none repeat scroll 0% 0%; 
  width: 300px; 
  height: 40px; 
  z-index: 2; 
  font-size: 30px; 
  color: white; 
  font-weight: bold; 
  text-align: center; 
  right: -70px; 
  transform: rotate(45deg); 
  top: 60px; 
  display: block;
  transition: 0.2s ease-in-out;
}
<div class="container">
  <nav>
    <span class="title">Dummy Example</span>
    <button>Home</button>
    <button>Pricing</button>
    <button class="right">Contact us</button>
    <button class="right">Log in</button>
  </nav>
  <div class="content"></div>
  <div id="bandeau">
    <span>I will be back !</span>
  </div>
</div>

Is there a way to acheive this or is it impossible ?

Thanks

toto1911
  • 431
  • 2
  • 18
  • Read more here: https://stackoverflow.com/questions/3680429/click-through-div-to-underlying-elements – yanca Mar 06 '20 at 12:59
  • Thanks but it doesn't solve my issue, which is I need to be able de catch the `:hover` event on my element, but with `pointer-events` it does not seem possible – toto1911 Mar 06 '20 at 13:07

2 Answers2

1

In your example you could do it easily on a hover on the whole nav element like

nav:hover + .content + .bandeau {  opacity: 0.4; }

Or you can move the banner element to the because it's an absolute positioned element. Then a hover on the login button (with the .right class) will make it transparent:

body {margin:0; padding:0;}
.title {font-weight:bold;margin-right:10px;}
.container {margin: 0 auto;width:80%;position:relative;overflow:hidden;}
.content {height:300px;border: 1px solid #c8c8c8;}
nav {background-color:#efebe0;padding:20px;}
button {padding:10px;background-color:#9ebf00;border: 1px solid #86a200;border-radius:5px;margin: 0 5px 0 5px;}
button.right {float:right;}

.bandeau {
  position: absolute; 
  background: red none repeat scroll 0% 0%; 
  width: 300px; 
  height: 40px; 
  z-index: 2; 
  font-size: 30px; 
  color: white; 
  font-weight: bold; 
  text-align: center; 
  right: -70px; 
  transform: rotate(45deg); 
  top: 60px; 
  display: block;
  transition: 0.2s ease-in-out;
  pointer-events:none;
}

.right:hover + .bandeau {
  opacity: 0.4;
}
<div class="container">
  <nav>
    <span class="title">Dummy Example</span>
    <button>Home</button>
    <button>Pricing</button>
    <button class="right">Contact us</button>
    <button class="right">Log in</button>
    <div class="bandeau">
      <span>I will be back!</span>
    </div>
  </nav>
  <div class="content"></div>
</div>

I know it's a bit different than a hover on the banner itself, but maybe this can give you some ideas :)

arvie
  • 722
  • 1
  • 5
  • 9
  • Thanks, I quite like this solution ! It's simple and effective. I didn't though about that. However I think I will go with the javascript approach that I will describe as a solution – toto1911 Mar 06 '20 at 14:24
0

I found a solution based on a comment on the thread linked by @yanca. I use document.elementFromPoint to chekc what cursor I should display (pointer or auto) based on the lement below the banner. Then I reuse document.elementFromPoint to transfer the click through

Here is the code :

document.addEventListener('DOMContentLoaded', function() {
  var bandeau = document.getElementById("bandeau");
  bandeau.addEventListener('mousemove', e => {
    bandeau.style.display = "none";
    var elemUnder = document.elementFromPoint(e.clientX, e.clientY);
    bandeau.style.display = "block";
    var stylesUnder = getComputedStyle(elemUnder);
    bandeau.style.cursor = stylesUnder.cursor;
  });
  bandeau.addEventListener('click', e => {
    bandeau.style.display = "none";
    var elemUnder = document.elementFromPoint(e.clientX, e.clientY);
    bandeau.style.display = "block";
    elemUnder.click();
  });
}, false);
body {margin:0; padding:0;}
.title {font-weight:bold;margin-right:10px;}
.container {margin: 0 auto;width:80%;position:relative;overflow:hidden;}
.content {height:300px;border: 1px solid #c8c8c8;}
nav {background-color:#efebe0;padding:20px;}
button {padding:10px;background-color:#9ebf00;border: 1px solid #86a200;border-radius:5px;margin: 0 5px 0 5px;cursor:pointer;}
button.right {float:right;}

#bandeau {
  position: absolute; 
  background: red none repeat scroll 0% 0%; 
  width: 300px; 
  height: 40px; 
  z-index: 2; 
  font-size: 30px; 
  color: white; 
  font-weight: bold; 
  text-align: center; 
  right: -70px; 
  transform: rotate(45deg); 
  top: 60px; 
  display: block;
  transition: 0.2s ease;
}

#bandeau:hover {
  opacity:0.4;
  transition: 0.2s ease;
}
<div class="container">
  <div id="body">
    <nav>
      <span class="title">Dummy Example</span>
      <button>Home</button>
      <button>Pricing</button>
      <button class="right" onclick="alert('click contact')">Contact us</button>
      <button class="right" onclick="alert('click login')">Log in</button>
    </nav>
    <div class="content"></div>
  <div>
  <div id="bandeau">
    <span>I will be back !</span>
  </div>
</div>

Thanks for the help !!

toto1911
  • 431
  • 2
  • 18