I'm developing a dropdown and I'm having an issue because I want to have an absolutely positioned container of items to appear when you hover over it, but the issue is that the shadow from this bleeds onto the actual dropdown itself. Here's a reproduction:
body {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 50px;
}
.dropdown {
position: relative;
width: 200px;
height: 40px;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
background-color: #efefef;
}
.items {
display: none;
position: absolute;
overflow: hidden;
overflow-y: auto;
width: 100%;
height: 100px;
top: 100%;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
background-color: #f7f7f7;
}
.dropdown:hover .items {
display: block;
}
.item {
padding: 5px 10px;
}
<div >
<div >
<div >a</div>
<div >b</div>
<div >c</div>
<div >d</div>
</div>
</div>
<div>hello</div>
As you can see, the top portion of the shadow from the .items
container is visible when you mouse over the dropdown. Here's a picture of what I'm referring to:
The obvious solution is to just make the box shadow apply to only the dropdown, but then the issue is that since the items
container is position absolute, it doesn't receive the box shadow.
Is there any way around this?
CodePudding user response:
I think Jackson has the right idea with using a pseudo element.
Although my approach would be the following:
.dropdown:hover::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
background-color: #efefef;
}
body {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 50px;
}
.dropdown {
position: relative;
width: 200px;
height: 40px;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
background-color: #efefef;
}
.items {
display: none;
position: absolute;
overflow: hidden;
overflow-y: auto;
width: 100%;
height: 100px;
top: 100%;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
background-color: #f7f7f7;
}
.dropdown:hover .items {
display: block;
}
.dropdown:hover::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
background-color: #efefef;
}
.item {
padding: 5px 10px;
}
<div >
<div >
<div >a</div>
<div >b</div>
<div >c</div>
<div >d</div>
</div>
</div>
<div>hello</div>
A second approach could be to grow the height of .dropdown on hover, and set the items list to a position not relative to .dropdown's height:
body {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 50px;
}
.dropdown {
position: relative;
width: 200px;
height: 40px;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
background-color: #efefef;
}
.items {
display: none;
position: absolute;
overflow: hidden;
overflow-y: auto;
width: 100%;
height: 100px;
top: 40px;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
background-color: #f7f7f7;
}
.dropdown:hover .items {
display: block;
}
.dropdown:hover {
height: 140px;
}
.item {
padding: 5px 10px;
}
<div >
<div >
<div >a</div>
<div >b</div>
<div >c</div>
<div >d</div>
</div>
</div>
<div>hello</div>
CodePudding user response:
You could add a :before
element on the .dropdown
with a smaller height than he items. Like this:
.dropdown:hover:before {
position: absolute;
content: "";
width: 100%;
height: 98px;
box-shadow: rgb(0 0 0 / 24%) 0px 6px 8px;
background: red;
bottom: -100px;
z-index: 0;
}
Also, remove the shadow from the .items
element.