sass的random()仅在编译时生成固定整数,非运行时真随机;css painting api可实现浏览器端动态随机,但兼容性差;svg data url是兼顾灵活性与兼容性的折中方案。

Random函数在Sass里根本不存在
Sass原生不提供 random() 函数——这是很多人查文档半天没找到、甚至怀疑自己版本太老的根本原因。Sass 3.3+ 确实加了 random($max),但它只在编译时运行,且只能生成整数;它不是CSS运行时的“真随机”,也不能用在@keyframes或伪元素动态样式里。
常见错误现象:random(100) 在Sass中能编译通过,但每次编译结果固定(比如永远是42),刷新页面毫无变化;有人试图在:hover里调用它,结果报错Undefined mixin or function "random"(其实是用了旧版Sass)。
- 确认Sass版本:执行
sass --version,低于3.3.0的必须升级 -
random($max)只接受一个参数,且必须是数字(不能是100px或blue) - 它返回的是整数,想得小数得手动除:比如
random(100) / 100得0.73
用Sass map + random()批量生成装饰性背景点
典型使用场景:给卡片加一堆大小、位置、透明度各异的浅色圆点作背景纹理。靠手写几十个div太蠢,用Sass循环+random()预生成最实际。
关键点在于:所有随机值必须在编译期确定,所以得用@for循环配合random(),把结果写进CSS规则里,而不是指望浏览器实时算。
立即学习“前端免费学习笔记(深入)”;
- 别用
@each遍历列表再random()——Sass里random()在循环内每次调用都真随机,但结果仍是静态的 - 控制数量:太多点(比如>200个)会让CSS体积暴涨,影响首屏解析
- 避免重复定位:用
random(100)生成left/top值时,记得加单位,比如#{random(100)}%
@for $i from 1 through 12 {
.bg-deco::before:nth-child(#{$i}) {
--size: #{random(8) + 2}px;
--left: #{random(100)}%;
--top: #{random(100)}%;
--alpha: #{random(30) / 100};
width: var(--size);
height: var(--size);
left: var(--left);
top: var(--top);
opacity: var(--alpha);
}
}纯CSS方案:用background-image: paint(...)实现运行时随机
如果真需要每次刷新页面都变、甚至滚动时动态更新,Sass编译期随机完全不够用。这时候得绕过Sass,用CSS Painting API写一个paint()函数,在浏览器里实时调用Math.random()。
兼容性代价明显:目前仅Chrome/Edge 65+支持,Firefox和Safari基本不跟。但它是唯一能让“随机”活起来的方式。
- 必须注册
CSS.paintWorklet.addModule(),路径要是同源的.js文件 - worklet脚本里不能访问
document或window,Math.random()是唯一可用的随机源 - 无法用在
:hover等伪类里触发重绘——paint函数只在尺寸或自定义属性变更时调用
示例用法:background-image: paint(randomDots);,然后在JS里定义registerPaint('randomDots', class {...}),里面用ctx.arc(x, y, r, 0, Math.PI * 2)画点。
更轻量的替代方案:用SVG data URL嵌入随机点
不想折腾Worklet,又嫌Sass循环生成的CSS太重?用JS生成一次SVG字符串,转成data URL塞进background-image,是个平衡点。它比Sass灵活(可基于viewport宽高动态算点数),又比Paint API兼容性好。
注意:data URL长度有限制(尤其IE),单个SVG别超4KB;点太多就分片,用多个background-layer叠。
- 生成时用
Math.random(),但只在页面加载时跑一次,之后就是静态资源 - SVG里点坐标用
<circle cx="..." cy="..." r="..." fill="..."></circle>,别用filter模糊——移动端性能差 - 把data URL存在
style标签里或data-属性上,避免内联过长导致HTML解析阻塞
一句话收住:真正的“随机感”从来不在CSS里,而在于你愿意在编译期、运行时还是构建期做取舍。Sass的random()只是个占位符,别把它当魔法用。










