使用位置绝对元素防止阴影出血?
Prevent shadow bleeding with position absolute element?
我正在开发一个下拉菜单,但我遇到了一个问题,因为我希望当您将鼠标悬停在它上面时,它会出现一个绝对定位的项目容器,但问题是这个阴影会渗入实际下拉菜单本身。这是一个复制品:
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 class="dropdown">
<div class="items">
<div class="item">a</div>
<div class="item">b</div>
<div class="item">c</div>
<div class="item">d</div>
</div>
</div>
<div>hello</div>
如您所见,当您将鼠标悬停在下拉菜单上时,.items
容器的阴影的顶部可见。这是我所指的图片:
最明显的解决方案是让框阴影仅应用于 下拉列表,但问题是由于 items
容器是绝对位置,它没有收到盒子阴影。
有什么解决办法吗?
您可以在 .dropdown
上添加一个 :before
元素,其高度小于他的项目。像这样:
.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;
}
此外,删除 .items
元素的阴影。
我认为 Jackson 使用伪元素的想法是正确的。
尽管我的方法如下:
.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 class="dropdown">
<div class="items">
<div class="item">a</div>
<div class="item">b</div>
<div class="item">c</div>
<div class="item">d</div>
</div>
</div>
<div>hello</div>
第二种方法可能是在悬停时增加 .dropdown 的高度,并将项目列表设置到与 .dropdown 的高度无关的位置:
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 class="dropdown">
<div class="items">
<div class="item">a</div>
<div class="item">b</div>
<div class="item">c</div>
<div class="item">d</div>
</div>
</div>
<div>hello</div>
我正在开发一个下拉菜单,但我遇到了一个问题,因为我希望当您将鼠标悬停在它上面时,它会出现一个绝对定位的项目容器,但问题是这个阴影会渗入实际下拉菜单本身。这是一个复制品:
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 class="dropdown">
<div class="items">
<div class="item">a</div>
<div class="item">b</div>
<div class="item">c</div>
<div class="item">d</div>
</div>
</div>
<div>hello</div>
如您所见,当您将鼠标悬停在下拉菜单上时,.items
容器的阴影的顶部可见。这是我所指的图片:
最明显的解决方案是让框阴影仅应用于 下拉列表,但问题是由于 items
容器是绝对位置,它没有收到盒子阴影。
有什么解决办法吗?
您可以在 .dropdown
上添加一个 :before
元素,其高度小于他的项目。像这样:
.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;
}
此外,删除 .items
元素的阴影。
我认为 Jackson 使用伪元素的想法是正确的。
尽管我的方法如下:
.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 class="dropdown">
<div class="items">
<div class="item">a</div>
<div class="item">b</div>
<div class="item">c</div>
<div class="item">d</div>
</div>
</div>
<div>hello</div>
第二种方法可能是在悬停时增加 .dropdown 的高度,并将项目列表设置到与 .dropdown 的高度无关的位置:
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 class="dropdown">
<div class="items">
<div class="item">a</div>
<div class="item">b</div>
<div class="item">c</div>
<div class="item">d</div>
</div>
</div>
<div>hello</div>