用box-shadow实现物体投影效果

Achieve object projection effect with box-shadow

我正在尝试在 CSS 中实现此效果:

这是我的代码:

#test {position: relative;margin: 100px;}
#test::after {
  background-color: maroon;
  box-shadow: 0 -50px 10px 7px gray;
  height: 45px;
  left: -15px;
  position: absolute;
  top: 40px;
  transform: perspective(150px) rotateX(-45deg);
  transform-origin: center bottom 0;
  width: 60px;
  content: "";
}
<div id="test"></div>

但是我没有用投射阴影达到预期的效果。我想知道仅使用 CSS 是否有可能做到这一点?

Fiddle Demo

根据W3 spec, "the 'box-shadow' property attaches one or more drop-shadows to the box". The shadow you want to create is not a drop shadow所以没有CSS会在图片中产生阴影

最接近的方法是使用 negative spread radius:

将阴影推离边缘

body {
  padding-top: 50px;
}
#test {
  margin: 0 auto;
  background-color: maroon;
  box-shadow: 0 -20px 7px -6px black;
  height: 45px;
  width: 60px;
  transform: perspective(150px) rotateX(-45deg);
  transform-origin: center bottom 0;
}
<div id="test"></div>

也许是这样的?我添加了另一个代表阴影的元素:

#shadow {
  height: 90px;
  left: -15px;
  position: absolute;
  top: 30px;
  background: rgba(0, 0, 0, 0);
  width: 60px;
  transform: perspective(50px) rotateX(25deg);
  box-shadow: 0 -106px 20px 17px #808080;
}

https://jsfiddle.net/zcyy09mp/4/

, I would generally recommend the approach used in my fiddle 中所述(即使用另一个伪元素)或 Martin 的答案中的那个(即使用额外元素)但正如你提到的那样另一个伪元素元素已经被使用并且你试图避免任何额外的元素,另一种方法是使用渐变作为父元素的 background 。通过background-positionbackground-size使用适当的左右渐变,我们不仅可以得到形状,还可以得到非常类似于阴影模糊性质的效果。

下面是一个示例片段:(输出也相当灵敏,您可以将鼠标悬停在它上面

#test {
  position: relative;
  height: 100px;
  width: 100px;
  margin: 100px;
  background: linear-gradient(to bottom right, transparent 45%, gray 55%), linear-gradient(to bottom left, transparent 45%, gray 55%), linear-gradient(to bottom, transparent, gray), linear-gradient(gray, gray);
  background-repeat: no-repeat;
  background-size: 30px 95%, 30px 95%, calc(100% - 60px) 8px, calc(100% - 60px) calc(100% - 8px);
  background-position: 0% 100%, 100% 100%, 50% 4px, 50% 100%;
}

#test::after {
  position: absolute;
  content: "";
  background-color: maroon;
  width: 100%;
  height: 45%;
  left: 0px;
  top: 100%;
  transform: perspective(150px) rotateX(-45deg);
  transform-origin: center top 0;
}

/* just for demo */

#test {
  transition: all 1s;
}
#test:hover {
  height: 200px;
  width: 200px;
}
<div id="test"></div>


在下面的代码片段中,我为每个渐变赋予了不同的颜色,只是为了直观地展示它是如何实现的。

#test {
  position: relative;
  height: 100px;
  width: 100px;
  margin: 100px;
  background: linear-gradient(to bottom right, transparent 45%, red 55%), linear-gradient(to bottom left, transparent 45%, blue 55%), linear-gradient(to bottom, transparent, green), linear-gradient(rebeccapurple, rebeccapurple);
  background-repeat: no-repeat;
  background-size: 30px 95%, 30px 95%, calc(100% - 60px) 8px, calc(100% - 60px) calc(100% - 8px);
  background-position: 0% 100%, 100% 100%, 50% 4px, 50% 100%;
}

#test::after {
  position: absolute;
  content: "";
  background-color: maroon;
  width: 100%;
  height: 45%;
  left: 0px;
  top: 100%;
  transform: perspective(150px) rotateX(-45deg);
  transform-origin: center top 0;
}

/* just for demo */

#test {
  transition: all 1s;
}
#test:hover {
  height: 200px;
  width: 200px;
}
<div id="test"></div>