box-shadow
属性显然对于元素背后的光影很有用,它能提供一种立体感和分离感。但是 box-shadow
也有一些技巧,特别是关于阴影不必柔和,可以叠加,甚至不必特别靠近。
我们将要实现这些“方块按钮”,但最终我们将使用 box-shadow
来创建它们,所以让我们快速了解一下 box-shadow
的用法。
box-shadow
的基本用法是通过在元素下方应用阴影,使其看起来像是从表面抬起,从而赋予元素立体感。

应用于这些白色方块的轻微阴影是由以下代码实现的:
.module {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}
也就是说:
- 创建一个与该元素形状完全相同的副本(例如,尊重
border-radius
),并将其放置在元素下方 - 水平偏移 0,垂直偏移 1px(向下)
- 模糊 3px。在模糊之后有一个可选参数,称为扩展,它允许你扩展或收缩阴影,默认为 0(既不扩展也不收缩)。
- 阴影的背景色为黑色,不透明度为 0.2。
但这太基本了。来吧。我们可以变得更奇怪。考虑一下:
- 你可以对这些偏移进行极端的设置。
- 你完全可以不模糊阴影。
- 颜色不必是柔和的。
最重要的是
- 你可以应用多个阴影
这里有三个偏移不同的阴影,并且没有模糊

.module {
width: 100px;
height: 100px;
background: white;
box-shadow:
5px 5px 0 #FF9800,
10px 10px 0 #FFC107,
15px 15px 0 #607D8B;
}
我们可以进一步加大这些偏移,使“阴影”完全与元素分离

.module {
width: 50px;
height: 50px;
background: white;
box-shadow:
55px 55px 0 #FF9800,
110px 110px 0 #FFC107,
165px 165px 0 #607D8B;
}
所以现在我们知道我们可以使用无限数量的任何大小的阴影,并将它们放置在任何位置……我们可以用单个元素绘制像素画!Marcus Connor 使用此方法绘制了一个汉堡包、薯条和奶昔

Codrin Pavel 使用此方法绘制了史蒂夫·乔布斯

或者,Jay Salvat 使用大约 7500 个阴影绘制的蒙娜丽莎怎么样?

在稍微更实用的层面上,你可以叠加 box-shadow
来模拟三维效果和方向阴影。方块按钮!
技巧在于我们使用零模糊的阴影,并将它们叠加在一起。如果我们一次一个像素地这样做,并在执行此操作时交替使用侧面,那么阴影叠加的方式将使我们有机会创建 3D 盒子的外观。以下是基础知识:
.boxy-button {
--bottom-color: #999;
--right-color: #ddd;
box-shadow:
1px 0 0 var(--right-color),
1px 1px 0 var(--bottom-color),
2px 1px 0 var(--right-color),
2px 2px 0 var(--bottom-color),
3px 2px 0 var(--right-color),
3px 3px 0 var(--bottom-color),
4px 3px 0 var(--right-color),
4px 4px 0 var(--bottom-color);
}
继续这样做,我们就可以创建一个非常方块的按钮了。

在上面添加一些过渡,我们甚至可以使其感觉非常可按压
button {
font-family: Roboto, sans-serif;
padding: 1rem 2rem;
font-size: 2rem;
border: 0;
color: #333;
--top-color: #ccc;
--bottom-color: #999;
--right-color: #ddd;
background: var(--top-color);
transition: box-shadow 0.2s, transform 0.15s;
box-shadow: 1px 0 0 var(--right-color), 1px 1px 0 var(--bottom-color), 2px 1px 0 var(--right-color), 2px 2px 0 var(--bottom-color), 3px 2px 0 var(--right-color), 3px 3px 0 var(--bottom-color), 4px 3px 0 var(--right-color), 4px 4px 0 var(--bottom-color), 5px 4px 0 var(--right-color), 5px 5px 0 var(--bottom-color), 6px 5px 0 var(--right-color), 6px 6px 0 var(--bottom-color), 7px 6px 0 var(--right-color), 7px 7px 0 var(--bottom-color), 8px 7px 0 var(--right-color), 8px 8px 0 var(--bottom-color), -5px 20px 40px -8px #999;
}
button:focus, button:hover {
outline: 0;
box-shadow: 1px 0 0 var(--right-color), 1px 1px 0 var(--bottom-color), 2px 1px 0 var(--right-color), 2px 2px 0 var(--bottom-color), 3px 2px 0 var(--right-color), 3px 3px 0 var(--bottom-color), 4px 3px 0 var(--right-color), 4px 4px 0 var(--bottom-color), -5px 5px 12px -8px #999;
transform: translate(3px, 3px);
}
button:active {
outline: 0;
box-shadow: 1px 0 0 var(--right-color), 1px 1px 0 var(--bottom-color);
transform: translate(5px, 5px);
}

我们也可以对“外部”阴影使用一次一行阴影技术,通过每次稍微降低阴影的不透明度来模拟渐变。这使得更像一个方向阴影,看起来很酷。
这是一个示例,其中方向与其他方向相反(由于使用了负 box-shadow
偏移),并使用了方向阴影。

对于一个有趣的按钮来说,这实在是有太多的代码,但按钮不值得吗?使用少得多的代码,我们可以获得另一种非常有趣的偏移外观,只是这次使用了一些 inset
box-shadow
的技巧和少量伪元素来模拟边框的延续。
button {
background: none;
border: 5px solid black;
padding: 1.5rem 3rem;
box-shadow: 5px 5px red, 10px 10px black, inset 5px 5px white, inset 10px 10px black;
font-family: -system-ui, sans-serif;
font-weight: bold;
font-size: 2rem;
position: relative;
}
button::before, button::after {
content: "";
position: absolute;
background: black;
}
button::before {
top: 100%;
left: 5px;
height: 10px;
width: 5px;
}
button::after {
left: 100%;
top: 5px;
height: 5px;
width: 10px;
}
