本篇依然来自于我们的 《前端周刊》 项目!
由团队成员 嘿嘿 翻译,他的文章风格稳健而清晰,注重结构与逻辑的严谨性,善于用简洁的语言将复杂技术拆解成易于理解的知识点~
欢迎大家 进群 与他探讨 CSS random() 最新趋势,并持续追踪全球前端领域的最新动态!
编程语言里的随机函数真是太棒了。你可以用它们来制造变化,让东西看起来自然又有活力。但一直以来,CSS 里没法生成随机数。现在不一样了,random()
函数马上就要来了。你可以用它来创建随机的动画延时,把内容随机放在屏幕上任何位置,生成随机颜色,或者任何你想要的效果------完全不需要使用任何 JavaScript。
基本用法
这个新函数有三个参数:random(min, max, step)
。你设置一个最小值和最大值,定义随机数的范围。可以用任何类型的数字(整数、百分比、长度、角度等等),只要三个参数的类型一致就行。第三个步长参数可选,想要整数的时候特别有用。
比如,random(0, 100, 2)
会选择 0 到 100 之间的偶数,而 random(0turn, 1turn)
会是一个小数角度------基本上就是 0 到 360 度之间的任意小数。
下面我们通过几个例子来看看怎么用 random()
。先从用 HTML 和 CSS 做一个星空开始。
用 CSS 和 HTML 做星空

用随机放置的圆圈、发光效果和四角星做的纯 CSS 星空
xml
<html>
<body>
<div class=star></div>
<div class=star></div>
...
<div class=star></div>
</body>
</html>
先给每颗星创建一个 HTML 元素。然后画出天空,用白色的小圆圈来做星星。设置成固定定位,这样就能轻松地随机放置它们了。
css
body {
background-color: black;
}
.star {
background-color: white;
border-radius: 50%;
aspect-ratio: 1/1;
width: 3px;
position: fixed;
}
现在让星星分散开,把 top 和 left 属性设置成随机值。这里 top
(Y 轴)设为 0-100%,left
(X 轴)也是独立的随机值。默认情况下,每个 random()
函数都会用不同的随机种子生成不同的随机值。
css
.star {
background-color: white;
border-radius: 50%;
aspect-ratio: 1/1;
width: 3px;
position: fixed;
top: random(0%, 100%);
left: random(0%, 100%);
}

随机放置的圆点
为了让效果更生动,我们也把"星星"的大小做成随机的。
css
.star {
background-color: white;
border-radius: 50%;
aspect-ratio: 1/1;
width: random(2px, 10px, 1px);
position: fixed;
top: random(0%, 100%);
left: random(0%, 100%);
}
注意 top 和 left 的随机值用的是百分比,但 width
用的是像素。记住,不管用什么单位,每个参数都得保持一致。上面例子里的第三个参数确保星星大小按 1px
递增,这样能得到整数,让大小分布更均匀,变化更丰富。

大小随机的圆形星星
我们还能加点特效,比如用多层阴影和混合效果给星星加上微妙的光晕。
css
.star {
--star-size: random(--random-star-size, 1px, 7px, 1px);
background-color: white;
border-radius: 50%;
aspect-ratio: 1/1;
width: var(--star-size);
position: fixed;
top: random(0%, 100%);
left: random(0%, 100%);
filter: drop-shadow(0px 0px calc(var(--star-size) * 0.5) oklch(0.7 0.2 random(0, 100)))
drop-shadow(0px 0px calc(var(--star-size) * 2) white);
mix-blend-mode: hard-light;
}
共享随机值和自定义属性
--star-size
自定义属性让我们能重复使用生成的随机像素值,但是自定义属性配合 random()
有些重要的细节。首先,你会看到 random()
函数的第一个参数看起来像另一个自定义属性。这里用的 --random-star-size
名字叫做标识符,用来确保在其他用了相同标识符的 random()
调用中使用同样的随机值。
你可能会问,为什么需要这样?要知道,把自定义属性设为 CSS 函数跟其他编程语言里变量存储结果是不一样的。自定义属性更像是简单的文本替换。也就是说,无论你在哪里用 var()
调用这个属性,实际上更像是文本替换,把 var()
替换成你声明的属性内容。在这个例子里,意思就是又来一个 random()
调用,而不是函数的结果。
回到例子,理想的光晕模糊效果需要基于星星最终的随机大小。用 calc()
就能做到这点,用星星大小的倍数作为多层阴影的模糊大小。要做到这点就得获得同样的随机值,所以用命名标识符是对的。
第一个阴影还用 random()
通过 oklch()
选择色调,添加鲜艳的颜色,配合 hard-light
混合模式和柔和的白色光晕组合使用。这种组合给星星添加了微妙而生动的着色。

发光的随机圆形星星
用命名标识符可以在单个元素的不同属性之间共享随机值。这只是共享随机值的方法之一。random()
函数有很多种用法,看你的需求。你还可以用 element-shared
值让所有匹配的元素共享某个属性的随机值,或者两种方法混用,到处共享值。跟命名标识符不同的是,命名标识符在使用标识符的时候共享值,而 element-shared
会让所有应用这个属性的元素共享随机值。
在星空例子里看到这种效果的一个办法是加几个简单的四角星。
css
.star.fourpointed {
clip-path: shape(from 50% 0%,line to 50.27% 3.25%, ...);
--star-size: random(--random-four-point-size, 20px, 60px, 1px);
rotate: random(element-shared, -45deg, 45deg);
}

随机放置和旋转的四角星
用 CSS shape()
来定义四角星形状,裁剪掉圆形的白色背景。星星大小还是可以随机,但得放大一个数量级才好看。这些星星更逼真的样式是模仿星星图片里看到的衍射光芒。因为物理原因,它们都是同一个角度倾斜的。虽然可以设个固定角度,但随机角度更有趣更生动。要有效地做到这点,就得让所有四角星用同一个随机角度。
这就是 element-shared
派上用场的地方。element-shared
值为所有元素的这个属性生成一个共享的随机值。这样所有四角星就会以同样的随机角度旋转了。
这里是完整的星空例子,你可以试试:codepen.io/jdatapple/p...
随机放置的矩形
random()
还有很多其他用法。基于星空例子的思路,你可以试试把 random()
跟 grid
这样的布局工具结合使用。

随机放置、随机着色的矩形
在这个变化的例子里,网页区域被分成 100 行 100 列。然后随机颜色的矩形被随机放在网格里:
css
.grid {
display: grid;
--rows: 100;
--columns: 100;
grid-template-rows: repeat(var(--rows), 1fr);
grid-template-columns: repeat(var(--columns), 1fr);
width: 100vw;
height: 100vh;
}
.rectangle {
background-color: lch(100% 90% random(0deg, 360deg));
grid-area: random(1, var(--rows), 1) / random(1, var(--columns), 1);
}
你可以在任何支持 random()
的浏览器里看最终效果:codepen.io/ntim/pen/dP...
照片堆叠
另一个用 random()
的例子是创建看起来像是随意撒在一起的照片堆。你可以花时间精心摆放每张照片,或者让电脑在每次页面加载时自动生成。
沙漠风景照片堆,图片随机旋转和偏移放置
css
.stack img {
width: 100%;
grid-column: 1;
grid-row: 1;
border: 10px solid hsl(0, 100%, 100%);
box-shadow: 10px 10px 40px hsl(0, 0%, 0%, 20%);
--random-rotate: rotate(random(-1 * var(--rotate-offset), var(--rotate-offset)));
transition: .3s ease-out;
transform: var(--random-rotate);
transform-origin: random(0%, 100%) random(0%, 100%);
}
更棒的是,在交互里加入随机性也很简单。在图片的悬停状态加入随机平移,增加了趣味性:
css
.stack:hover img {
transform: var(--random-rotate) translateX(random(-1 * var(--translate-offset), var(--translate-offset))) translateY(random(-1 * var(--translate-offset), var(--translate-offset)));
}
幸运转盘

随机旋转示例,转盘分成 20 份,隔一个格子放一个表情符号,有个绿色的旋转按钮
random()
函数甚至能用来做需要不可预测结果的交互元素。幸运转盘演示完美地展示了这点。
css
@keyframes spin {
from {
rotate: 0deg;
}
to {
rotate: 10turn; /* 不支持 random() 的浏览器用这个 */
rotate: random(2turn, 10turn, by 20deg);
}
}
点击"SPIN"按钮时,@keyframe
动画用 random()
生成一个旋转值,决定转盘停在哪里。这个例子展示了现代 CSS 越来越强大的功能,在样式表里就能定义所有的交互、随机性和动画。
你可以在这里看实际效果:codepen.io/ntim/pen/Wb...
随机性使用参考
random()
有很多不同的用法,看你需要什么,以及想要怎样在元素之间共享随机性。
完全随机
两个属性得到不同的值,每个元素也都不同,所以你得到很多随机矩形。
css
.random-rect {
width: random(100px, 200px);
height: random(100px, 200px);
}
在元素内按名称共享
使用标识符,两个属性可以得到相同值,但每个元素还是不同,所以你得到很多随机正方形。
css
.random-square {
width: random(--foo, 100px, 200px);
height: random(--foo, 100px, 200px);
}
在元素间按属性共享
用 element-shared
,两个属性得到不同值,但所有元素共享,所以你得到很多相同的随机矩形。
css
.shared-random-rect {
width: random(element-shared, 100px, 200px);
height: random(element-shared, 100px, 200px);
}
按名称全局共享
同时用命名标识符和 element-shared
,两个属性得到相同值,所有元素都共享,所以你得到很多相同的随机正方形。
css
.shared-random-squares {
width: random(--foo element-shared, 100px, 200px);
height: random(--foo element-shared, 100px, 200px);
}
试试看,告诉我们怎么样
你现在就能在 Safari Technology Preview 里试用 random()
函数!不过要注意,CSS 工作组还在讨论规范,关于这个方法是否最适合开发者的需求,还有几个问题没解决。
虽然上面的例子展示了很棒的可能性,我们正在积极征求 Web 开发社区的反馈来帮助确定最终方向,你能帮上忙。如果你在 Safari Technology Preview 里试了 random()
,我们很想听听你的体验。什么好用?什么别扭?共享值的表达方式你觉得合理吗?有什么用不上的场景吗?对 element-shared
这个名字有更好的建议吗?你的反馈会直接影响这个功能的发展方向。这是你帮助塑造 CSS 的机会------试试看,告诉我们你的想法。