2

The .dropbtn button has styling attached to it so that when it is hovered over it shows the .dropdown-content div by adding opacity to that element. However, hovering over the spot below the button where the .dropdown-content appears seems to trigger the hover that should only be happening when I hover over .dropbtn. Why is this happening?

There are some "solutions" like adding overflow:hidden to the .dropdown and adding it back with the hover, but it effects the transform I have attached to the .dropdown-content. Adding display:none and display:block to .dropdown content also breaks the transform effect I want.

* {
 font-family:sans-serif;
}
body {
 background-image:linear-gradient(to right,#42b4ce,#fd3838);
}
.dropbtn {
  background:none;
  color: white;
  font-size: 16px;
  border: none;
  cursor:pointer;
  padding:0 0 10px;
}

.dropdown {
  position: relative;
  width: 160px;
  margin: 0 auto;
  display: block;
  
}

.dropdown-content {
  opacity:0;
  position: absolute;
  background-color: #f1f1f1;
  min-width: 400px;
  right:-80px;
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
  z-index: -1;
  transform-origin: top center;
  transform:rotate3d(-40, 4, 1.5, 45deg);
  transition:.2s;
  border-radius:10px;
}

.dropdown-content a {
  color: black;
  padding: 10px 14px;
  text-decoration: none;
  display: block;
}

.dropdown-content a:hover {color: purple;}

.dropdown:hover .dropdown-content {
 opacity:1;
 transform:rotate3d(0, 0, 0, 40deg);
 z-index:0;
}

.dropdown:hover .dropbtn {text-shadow:1px 1px 2px rgba(0,0,0,0.6)};
<body>
  <div class="dropdown">
      <button class="dropbtn">Dropdown</button>
      <div class="dropdown-content">
        <a href="#">Link 1</a>
        <a href="#">Link 2</a>
        <a href="#">Link 3</a>
      </div>
    </div>
</body>

3 Answers3

1

Add visibility: hidden; to the .dropdown-content class and visibility: visible to it when .dropdown is hovered. See code below.

* {
 font-family:sans-serif;
}
body {
 background-image:linear-gradient(to right,#42b4ce,#fd3838);
}
.dropbtn {
  background:none;
  color: white;
  font-size: 16px;
  border: none;
  cursor:pointer;
  padding:0 0 10px;
}

.dropdown {
  position: relative;
  width: 160px;
  margin: 0 auto;
  display: block;
  
}

.dropdown-content {
  opacity:0;
  position: absolute;
  background-color: #f1f1f1;
  min-width: 400px;
  right:-80px;
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
  z-index: -1;
  transform-origin: top center;
  transform:rotate3d(-40, 4, 1.5, 45deg);
  transition:.2s;
  border-radius:10px;
  visibility: hidden;
}

.dropdown-content a {
  color: black;
  padding: 10px 14px;
  text-decoration: none;
  display: block;
}

.dropdown-content a:hover {color: purple;}

.dropdown:hover .dropdown-content {
 opacity:1;
 transform:rotate3d(0, 0, 0, 40deg);
 z-index:0;
    visibility: visible;
}

.dropdown:hover .dropbtn {text-shadow:1px 1px 2px rgba(0,0,0,0.6)};
<body>
  <div class="dropdown">
      <button class="dropbtn">Dropdown</button>
      <div class="dropdown-content">
        <a href="#">Link 1</a>
        <a href="#">Link 2</a>
        <a href="#">Link 3</a>
      </div>
    </div>
</body>
Chris Sandvik
  • 1,787
  • 9
  • 19
0

One idea is to simply increase the height of the body so that the element will go behind it since it has negative z-index

* {
 font-family:sans-serif;
}
body {
 background-image:linear-gradient(to right,#42b4ce,#fd3838);
  margin:0;
  height:100vh;
}
.dropbtn {
  background:none;
  color: white;
  font-size: 16px;
  border: none;
  cursor:pointer;
  padding:10px;
}

.dropdown {
  position: relative;
  width: 160px;
  margin: 0 auto;
  display: block;
  
}

.dropdown-content {
  opacity:0;
  position: absolute;
  z-index:-1;
  background-color: #f1f1f1;
  min-width: 400px;
  right:-80px;
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
  transform-origin: top center;
  transform:rotate3d(-40, 4, 1.5, 45deg);
  transition:.2s;
  border-radius:10px;
}

.dropdown-content a {
  color: black;
  padding: 10px 14px;
  text-decoration: none;
  display: block;
}

.dropdown-content a:hover {color: purple;}

.dropdown:hover .dropdown-content {
 opacity:1;
 transform:rotate3d(0, 0, 0, 40deg);
 z-index:0;
}

.dropdown:hover .dropbtn {text-shadow:1px 1px 2px rgba(0,0,0,0.6)};
<body>
  <div class="dropdown">
      <button class="dropbtn">Dropdown</button>
      <div class="dropdown-content">
        <a href="#">Link 1</a>
        <a href="#">Link 2</a>
        <a href="#">Link 3</a>
      </div>
    </div>
</body>

Here is a related question to understand how this trick is working: z-index weird behavior?

And to understand why your gradient was covering the whole screen even if there is no height set on the body you can check this: How to remove the stripes that appears when using linear gradient property?

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
0

Just add pointer-events: none; for .dropdown-content and pointer-events: auto for selector .dropdown:hover .dropdown-content

Demo

Joe Koker
  • 931
  • 10
  • 20