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">
Link 1
Link 2
Link 3
</div>
</div>
</body>
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">
Link 1
Link 2
Link 3
</div>
</div>
</body>
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">
Link 1
Link 2
Link 3
</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?
Just add pointer-events: none; for .dropdown-content and pointer-events: auto for selector .dropdown:hover .dropdown-content
Demo
Related
I designed a dropdown menu for a webpage. It displays all 'dropdown-content' when clicking on 'dropbtn' in all browsers except Safari. In Safari only the first of my a tags is displayed, the others are also clickable, but not visible.
HTML:
<div id="dropdownmenu">
<div class="dropdown">
<button class="dropbtn">Menu</button>
<div class="dropdown-content">
Home
History
Releases
Kontakt
JFBmusic
</div>
</div>
</div>
CSS:
#media only screen and (max-width:860px) {
#dropdownmenu {
display:block;
}
}
#dropdownmenu {
display:none;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
top:0;
margin-top:50px;
display: none;
position: fixed;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown-content a:hover {
background-color: #ddd;
}
.dropdown-content a:visited {
color: black;
}
.dropdown:hover .dropdown-content {
display: block;
}
.dropdown:hover .dropbtn {
background-color: darkgrey;
}
How can I solve this problem?
Drop down menu is not showing after using overflow. I want use overflow in div but its not working on hover.
Here's my code.
.dropbtn {
background-color: #4CAF50;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropdown {
position: relative;
display: inline-block;
overflow:scroll;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown-content a:hover {background-color: #f1f1f1}
.dropdown:hover .dropdown-content {
display: block;
}
.dropdown:hover .dropbtn {
background-color: #3e8e41;
}
<div class="dropdown">
<button class="dropbtn">Dropdown</button>
<div class="dropdown-content">
Link 1
Link 2
Link 3
</div>
</div>
You can see layout current show
I want to this
To achieve that, you have to set overflow:scroll to the button instead of giving overflow to the drop down content.
Try this.
.dropbtn {
background-color: #4CAF50;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
overflow:scroll;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown-content a:hover {background-color: #f1f1f1}
.dropdown:hover .dropdown-content {
display: block;
}
.dropdown:hover .dropbtn {
background-color: #3e8e41;
}
<div class="dropdown">
<button class="dropbtn">Dropdown</button>
<div class="dropdown-content">
Link 1
Link 2
Link 3
</div>
</div>
I want to maintain the hover state while hovering on margin. Things are working fine when I remove position absolute. Technically everything seems to be fine. The element which has margin is in the inside of element which is being hovered. Is it the expected behaviour if not then what is issue exactly.
.dropbtn {
background-color: #4CAF50;
color: white;
padding: 16px;
font-size: 16px;
border: none;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
margin-top:20px;
background-color: #f1f1f1;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown-content a:hover {background-color: #ddd;}
.dropdown:hover .dropdown-content {display: block;}
.dropdown:hover .dropbtn {background-color: #3e8e41;}
<div class="dropdown">
<button class="dropbtn">Dropdown</button>
<div class="dropdown-content">
Link 1
Link 2
Link 3
</div>
</div>
This is the expected behavior. Even though .dropdown-content is a child of .dropdown, since .dropdown-content is absolutely positioned, it's as though it's floating outside of .dropdown. If you inspect the .dropdown element in your browser, you'll see that its size only covers the .dropbtn and does not include .dropdown-content.
One way to fix this is to use padding instead of margin on .dropdown-content. However this will expand the size of the content and not leave a gap like it would by using margin.
So if you want to keep the 20px gap between the button and the hover menu, you can add another div around the links:
<div class="dropdown">
<button class="dropbtn">Dropdown</button>
<div class="dropdown-content">
<div class="dropdown-inner">
Link 1
Link 2
Link 3
</div>
</div>
</div>
And then put the background / shadow styles on the inner div instead:
.dropbtn {
background-color: #4CAF50;
color: white;
padding: 16px;
font-size: 16px;
border: none;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
padding-top: 20px;
min-width: 160px;
z-index: 1;
}
.dropdown-inner {
background-color: #f1f1f1;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
https://codepen.io/anon/pen/RJxGmp
An aproach to achive this is to use a pseudo element (:before) so you can place an invisible block on the gap of this two elements, so you dont lose the hover state when you reach the end of the dropdown container
.dropbtn {
background-color: #4CAF50;
color: white;
padding: 16px;
font-size: 16px;
border: none;
display:block;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown:after{
content:"";
position:absolute;
left:0px;
bottom:-20px;
display: none;
vertical-align: bottom;
width: 100%;
min-width: 160px;
height: 20px;
background-color: transparent;
}
.dropdown-content {
display: none;
position: absolute;
margin-top:20px;
background-color: #f1f1f1;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown-content a:hover {background-color: #ddd;}
.dropdown:hover .dropdown-content {display: block;}
.dropdown:hover:after{ display:inline-block;}
.dropdown:hover .dropbtn {background-color: #3e8e41;}
<div class="dropdown">
<button class="dropbtn">Dropdown</button>
<div class="dropdown-content">
Link 1
Link 2
Link 3
</div>
</div>
I want the contents of the dropdown to fade in over 0.3 seconds when hovered over using the transition property. I have it working when hovering over tabs.
li.dropdown {
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content a:hover {
background-color: #f1f1f1
}
.dropdown:hover .dropdown-content {
display: block;
}
<li class="dropdown">
Dropdown
<div class="dropdown-content">
Link 1
Link 2
Link 3
</div>
</li>
Try this, First make opacity:0 to your dropdown item and use transition and when you are going to hover on the block then that opacity:0 block should be opacity:1
li.dropdown {
display: inline-block;
}
.dropdown-content {
opacity: 0;
transition: opacity .3s ease-in-out;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content a:hover {
background-color: #f1f1f1
}
.dropdown:hover .dropdown-content {
opacity: 1;
}
<li class="dropdown">
Dropdown
<div class="dropdown-content">
Link 1
Link 2
Link 3
</div>
</li>
How about using CSS property transform for this?
The trick would be to scale down to 0 your dropdown content, then back to normal on hover.
.dropdown-content {
transform: scale(0);
}
.dropdown:hover .dropdown-content {
transform: scale(1);
}
You can change transform-origin value if you want a different starting point.
jsFiddle
li.dropdown {
display: inline-block;
}
.dropdown-content {
transform: scale(0);
transform-origin: 15% 0;
transition: transform 300ms ease-out;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content a:hover {
background-color: #f1f1f1
}
.dropdown:hover .dropdown-content {
transform: scale(1);
}
<li class="dropdown">
Dropdown
<div class="dropdown-content">
Link 1
Link 2
Link 3
</div>
</li>
I am using this button drop down located here. I need to make it look like the below picture
when you hover the drop down its flush with the left side of the button how can I make it flush to the right side and not the left.
*.dropbtn {
background-color: #4CAF50;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown-content a:hover {
background-color: #f1f1f1
}
.dropdown:hover .dropdown-content {
display: block;
}
.dropdown:hover .dropbtn {
background-color: #3e8e41;
}
<div class="dropdown">
<button class="dropbtn">Dropdown</button>
<div class="dropdown-content">
Link 1
Link 2
Link 3
</div>
</div>
you just need to add right:0 to dropdown-content, because by default the position:absolute it is aligned to left (like left:0)
.dropbtn {
background-color: #4CAF50;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropdown {
position: relative;
display: inline-block;
/* demo */
left: 300px
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
right: 0
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown-content a:hover {
background-color: #f1f1f1
}
.dropdown:hover .dropdown-content {
display: block;
}
.dropdown:hover .dropbtn {
background-color: #3e8e41;
}
<div class="dropdown">
<button class="dropbtn">Dropdown</button>
<div class="dropdown-content">
Link 1
Link 2
Link 3
</div>
</div>
Adding dir="rtl" attribute to you dropdown div will solve your issue.
<div class="dropdown" dir="rtl">
Check here if this is the result you want to get?