我正在尝试在两个元素上添加一个框阴影,每个元素都有可变宽度.我想要的结果如下:
我一直试图通过覆盖重叠框阴影的伪元素来获得这个结果,但由于它们需要具有透明度,我似乎无法找到一个解决方案,其中框的边缘没有小的重叠伪元素也不会调整到正确的宽度.
顶盒也不一定需要顶部边框来解决我的问题.
HTML:
<div>
<p></p>
</div>
<div>
<p></p>
</div>
SCSS:
div {
display: inline-block;
margin: 75px;
width: 200px;
height: 50px;
position: relative;
p {
position: absolute;
top: 100%;
left: 0;
height: 300px;
width: 250px;
}
&, p {
background: #ededed;
}
}
div:last-child p {
width: 150px
}
div {
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.2);
p {
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.2);
}
}
编辑:
通常情况下我不会考虑JS的布局,但因为在我的特定情况下,在用户交互发生之前,这些框将不可见,我使用了一个脚本来解决我的问题.
当dom准备好时,脚本会判断顶部元素是否大于底部元素,并分别为其添加“大”或“小”类.通过了解,我们知道伪元素的宽度应该继承哪个元素.只要元素不会以改变哪个元素更大的方式调整大小,这就可以正常工作.
还有一个更清洁的解决方案,不需要JS和一个伪元素,因为只需要一个盒子大小模糊和没有传播.
小提琴:
Blur and spread combined (JS),
最终结果并不完美,因为您可以在此屏幕截图中看到所有白色背景都替换为黑色:
当您查看左侧框的左上角时,您可以看到边框阴影有轻微的曲线.
无论如何,它足够接近我.
如果有人找到一个解决方案,结果与使用css的第一个小提琴相似,我会非常感激.
最佳答案 您有一个简单的解决方案,但它是一个实验性功能,它的支持有限.
使用过滤器:在基本元素上投影,投影应用于此元素的复合结果以及所有后代
div {
display: inline-block;
margin: 75px;
width: 150px;
height: 50px;
position: relative;
-webkit-filter: drop-shadow(0px 0px 5px rgba(255, 0,0,0.7));
filter: drop-shadow(0px 0px 2px red);
}
div p {
position: absolute;
top: 100%;
left: 0;
height: 300px;
width: 250px;
margin: 0px;
}
div, div p {
background: #ededed;
}
#second p {
width: 100px;
}
<div>
<p></p>
</div>
<div id="second">
<p></p>
</div>
另一种方法,将在任何浏览器中运行,使用阴影的伪元素:
div {
display: inline-block;
margin: 75px;
width: 150px;
height: 50px;
position: relative;
}
div p {
position: absolute;
top: 100%;
left: 0;
height: 300px;
width: 250px;
margin: 0px;
}
div, div p {
background: #ededed;
}
#second p {
width: 100px;
}
div:after, p:after {
content: "";
position: absolute;
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
box-shadow: 0px 0px 2px 6px rgba(0,255,0,0.7);
z-index: -10;
}
<div>
<p></p>
</div>
<div id="second">
<p></p>
</div>
另一种方法是剪切阴影.这是很差的支持,需要大量的手动调整,但最终的结果可能是最好看的.
演示仅适用于webkit
div {
display: inline-block;
margin: 75px;
width: 300px;
height: 50px;
position: absolute;
}
div p {
position: absolute;
top: 100%;
left: 0;
height: 100px;
width: 200px;
margin: 0px;
}
div, div p {
background: #ededed;
}
div:after, p:after {
content: "";
position: absolute;
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
box-shadow: 0px 0px 15px 15px rgba(255,0,0,0.2);
z-index: -10;
}
p:after {
-webkit-clip-path: polygon(0% 30px, 230px 30px, 260px 60px, 100% 100%, 0% 100%);
}
div:after {
-webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 260px 100%, 230px 80px, 0% 80px);
}
<div>
<p></p>
</div>