Css: box-shadow 的妙用

Sean 5 2026-03-26

最近在写代码的时候,需要实现一个带窗户的楼宇小图标。因为图标本身挺简单的,就想着自己用 CSS 手搓一个。按常规思路,楼房的主体用一个块元素,里面的窗户用几个 span 或者 div 实现,然后绝对定位一下。

但是感觉为了一个小图标,就增加了几个没有意义的DOM节点,不够优雅,并且DOM树很臃肿,也影响重排重绘。于是我想到了用CSS的 box-shadow 来实现。

核心思路

box-shadow 通常都被用来做阴影渲染,但其实有个玩法:当 blur (模糊半径)和 spread(扩张半径)都设置为 0 的时候,阴影就会变成和原元素1:1等大的克隆体。然后我们再通过设置X轴和Y轴的偏移量进行布局,就可以实现我们想要的效果。

代码实现

HTML,创建一个父标签(楼房主体)即可

<div class="building-icon"></div>

CSS:用为元素 ::before 画出第一个窗户,然后用 box-shadow 复制出另外三个

.building-icon{
    width: 18px;
    height: 22px;
    background: #4a90d9;
    border-radius: 4px 4px 0 0;
    position: relative;

    &::before {
      content: '';
      position: absolute;
      width: 4px;
      height: 4px; 
      top: 6px;
      left: 4px;
      border-radius: 1px;
      background: rgba(255, 255, 255, .6);

      box-shadow: 
          6px 0 0 rgba(255, 255, 255, .6), 
          0 6px 0 rgba(255, 255, 255, .6), 
          6px 6px 0 rgba(255, 255, 255, .6);  
    }
}

效果如图:

总结

优点:

  1. DOM 结构简单:不会产生额外的 DOM 元素,让 HTML 结构保持干净。

  2. 性能更好:减少了重排重绘。box-shadow 本身不占文档流,也不影响实际布局,纯粹是视觉上的克隆。

缺点:

  1. 只适合简单元素:这种写法本质上是在玩坐标系,如果复杂图案,代码可读性会很差。

  2. 不适合复杂交互:复杂的图案不入SVG或切图高效,且也无法单独绑定事件。