想在网页背景里搞出棋盘格图案不难,可一旦想要把那些小方块的棱角磨圆润,再在每个格子交点上塞一颗小星星,常规的CSS写法就有点不够用了。翻来翻去试了好多法子,最后发现一个有点野的路子——用重复渐变画出网格骨架,再借一个编码过的SVG把星星图案精准贴在每个交叉点上。整个过程不需要折腾canvas,也不用堆一堆div,纯粹靠background属性叠罗汉就能搞定。
啥是重复线性渐变
repeating-linear-gradient 这个CSS函数能生成一张重复平铺的渐变图。跟普通的线性渐变不一样,它不会只画一次就结束,而是把定义好的颜色段当模板,像铺瓷砖一样在整个背景区域里无限复制。比如写 repeating-linear-gradient(to right, red 0px, red 10px, blue 10px, blue 20px),浏览器就会生成红蓝交替的竖条纹,每条宽10像素,从左到右一直铺满。
搭骨架
先搞出一个基础的棋盘格网格。用两层 repeating-linear-gradient 叠起来,一层画水平方向的白色线框,一层画垂直方向的白色线框。两层一交叉,自然就切出了一个个独立的小方块。
.box {
background:
repeating-linear-gradient(
to right, transparent,
transparent 50px,
white 50px,
white 55px
),
repeating-linear-gradient(
to bottom, transparent,
transparent 50px,
white 50px,
white 55px
),
linear-gradient(45deg, #f8a5c2, #6c5ce7);
}这段代码里,第一个渐变生成竖向的白色条纹:从透明开始,保持50像素透明,然后突然变成白色,白色只占5像素宽,接着又变回透明。第二个渐变完全一样,只是方向改成 to bottom,生成横向的白色条纹。两层叠在一起,透明区域就露出了底层的粉色到蓝色渐变,而白色条纹相交的地方恰好围出一个个50×50像素的透明方块。底层那个45度线性渐变是整块背景的底色,被白色网格切割后,每个格子里的颜色其实还是连续的渐变过渡。
写代码的时候注意,白色条纹的宽度(5像素)决定了格子之间的缝隙粗细。如果希望格子之间挨得更紧,就把 55px 改成接近 50px 的值,比如 51px;想要宽边框,就加大差值。另外,透明区域的尺寸 50px 直接决定了每个方格的边长,这个数字后面还要跟星星图案的位置对齐,改的时候要前后一致。
贴星星
现在每个格子交叉点上还是空的。目标是在每条白色横线和白色竖线的交叉中心,也就是每个格子左上角那个点,放一颗小星星。这需要在 background 属性里再加一层图像,而且这层图像必须是重复平铺的,平铺的间距恰好等于格子宽度(55像素),同时偏移量要让星星正好落在交叉点上。
.box {
background:
repeat left -17px top -22px / 55px 55px
url("data:image/svg+xml,
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 35px 35px'>
<foreignObject width='35px' height='35px'>
<div xmlns='http://www.w3.org/1999/xhtml' style='color:white; font-size:35px'>✦</div>
</foreignObject>
</svg>"
),
repeating-linear-gradient(
to right, transparent,
transparent 50px,
white 50px,
white 55px
),
repeating-linear-gradient(
to bottom, transparent,
transparent 50px,
white 50px,
white 55px
),
linear-gradient(45deg, #f8a5c2, #6c5ce7);
}拆开来看,repeat 关键字告诉浏览器这张SVG小图要像墙纸一样平铺。紧接着的 left -17px top -22px / 55px 55px 分成了两截:斜杠左边是背景图的起始位置(向左偏移17像素,向上偏移22像素),斜杠右边是每张平铺单元的尺寸(宽55像素,高55像素)。为什么偏移量是 -17px 和 -22px?因为星星图案本身有35像素大小,而格子交叉点位于网格线的交汇处。经过反复试错,把星星往左上挪一点,才能让它的中心对准白色线框的十字交叉口。偏移数值跟星星的 font-size 以及格子尺寸直接挂钩,换不同大小的星星需要重新微调。
SVG 部分用了 foreignObject 在里面塞了一个HTML的 div,这个 div 只放了一颗黑色小星星的字符实体 ✦。通过 style="font-size:35px" 控制星星的大小,这个尺寸越大,覆盖的圆角范围就越大——实际上星星的边缘会遮住底层方格的尖角,视觉上相当于给格子磨了圆角。颜色设为白色,这样在深色渐变背景上能跳出来。注意整个SVG的 viewBox 和 foreignObject 的宽高都写成35像素,跟 font-size 保持一致,避免缩放变形。
鼠标滑过变半透
想要加点交互效果,可以在鼠标悬停时把白色线框变成半透明,同时把星星图层撤掉。这里不删除星星图层,而是重新写一套 background 属性,只保留渐变层,星星那行直接省略。白色线条的颜色从纯白 white 换成带透明通道的 rgb(255 255 255 / 0.5),半透明值0.5让底下的渐变底色能透上来。
.box:hover {
background:
repeating-linear-gradient(
to right, transparent,
transparent 50px,
rgba(255, 255, 255, 0.5) 50px,
rgba(255, 255, 255, 0.5) 55px
),
repeating-linear-gradient(
to bottom, transparent,
transparent 50px,
rgba(255, 255, 255, 0.5) 50px,
rgba(255, 255, 255, 0.5) 55px
),
linear-gradient(45deg, #f8a5c2, #6c5ce7);
box-shadow: 10px 10px 20px rgba(108, 92, 231, 0.3);
}悬停时还加了一个外发光 box-shadow,让整个模块浮起来。注意 repeating-linear-gradient 里的透明段和白色段的位置数字(50px, 55px)必须跟之前完全一致,否则网格线会错位。半透明的白色在深色背景上会呈现一种类似磨砂玻璃的效果,跟星星消失后的干净画面挺搭。
调参避坑表
| 参数位置 | 常见取值 | 作用说明 |
|---|---|---|
| 透明段终点 | 50px | 控制方格边长 |
| 白色段终点 | 55px | 控制网格线粗细 |
| 星星偏移X | -17px | 微调水平对位 |
| 星星偏移Y | -22px | 微调垂直对位 |
| 星星字体大小 | 35px | 决定圆角覆盖范围 |
调试的时候最容易翻车的是星星跑偏。如果发现星星不在十字交叉点上,可以单独把渐变层注释掉,只看星星的平铺效果,然后一点点调整偏移量。偏移量用负数表示向左或向上移动星星的起始绘制点。还有一个细节:白色线条的宽度(5像素)加上偏移量,必须保证星星的直径能盖住方块的尖角,否则圆角效果会露馅。如果想换其他符号,比如实心圆点 • 或者五角星 ★,直接在SVG的 div 里替换字符就行,注意某些特殊符号在不同操作系统下的显示可能不太一样。
