← 回總覽

【第 3672 期】CSS 迎来原生随机能力:random() 与 random-item() 初探

📅 2026-03-18 09:03 前端早读课 软件编程 6 分鐘 6336 字 評分: 82
CSS Web 标准 前端开发 生成式设计 random()
📌 一句话摘要 本文详细介绍了 CSS 新规范中引入的 `random()` 与 `random-item()` 原生随机函数及其复杂的共享机制。 📝 详细摘要 文章深入探讨了《CSS Values and Units Module Level 5》草案中新增的随机化能力。CSS 长期以来作为确定性语言,通过 `random()`(区间随机)和 `random-item()`(离散随机)打破了这一局限。重点解析了这两个函数的语法,包括步进取值(Step)以及极其灵活的共享选项(auto、虚线标识符、element-shared、fixed),这些选项允许开发者在属性间、元素间乃至全局范围内

Alvaro Montoro 2026-03-18 09:03 福建

!Image 1

CSS 正在突破一贯的确定性逻辑,迎来原生随机生成能力。

前言

CSS 正在突破一贯的确定性逻辑,迎来原生随机生成能力。随着random()random-item()被写入新规范,开发者今后可直接用 CSS 实现随机尺寸、颜色、布局与离散取值,为网页设计带来更灵活、更富表现力的变化。今日前端早读课文章由 @Alvaro Montoro 分享,@飘飘编译。

译文从这开始~~

CSS 工作组已经发布了《Values and Units Module Level 5》,其中引入了仅凭 CSS 就能生成随机内容的原生机制。本文是对一篇长文的精华概述,主题正是 CSS 中的随机性。 【早阅】使用集合在 JavaScript 中生成唯一随机数

一直以来,CSS 都是一门确定性的语言:相同的输入,永远得到相同的输出,分毫不差。而如今,随着两个全新随机函数的加入,这一点即将被改写。

这篇文章会直接切入这一特性本身。若你想看到更完整的梳理 —— 包括 CSS 随机化的发展历程、这一特性的工作原理,以及它对 CSS 这门语言意味着什么,敬请期待后续。

在写下这篇文章时,这一特性尚未得到广泛支持 —— 目前只有 Safari 从 26.2 版本开始对random()提供了部分支持。这篇文章更像是一次对规范本身以及即将到来功能的前瞻性介绍。

截至 2026 年 2 月,CSS 原生随机特性的支持情况:

| 特性 | Safari | Chrome | Firefox | | --- | --- | --- | --- | | random() | 26.2 | X | X | | random-item() | X | X | X |

下面就来看看这两个新函数。

#### random() random()会在给定区间内返回一个随机值。它最基础的写法接收两个参数 —— 最小值与最大值 —— 并在这一区间中生成任意一个结果。

例如: div {   width: random(200px, 500px); } / 可能的结果: - width: 230px; - width: 417px; - width: 308.342px; / 可以注意到,返回的结果并不局限于整数。只要落在这个范围内,哪怕是小数,也同样是合法值。

#### 按步进取值的随机数

不过,有时候我们并不想要小数值 —— 毕竟,谁会乐意在布局里和 “半个像素” 这种东西打交道呢?好在,这个函数还支持一个可选的第三参数,用来指定随机值的步长,也就是每次递增的单位。 【第3661期】不用 JS 也能精准定位?CSS Anchor Positioning 实战解析

实现方式也很简单:在函数末尾再加上第三个值即可。这个值表示取值时所遵循的步进间隔。 div {   rotate: random(0deg, 180deg, 10deg); } / 可能的结果: - rotate: 120deg; - rotate: 40deg; - rotate: 180deg; 不可能出现的结果: - rotate: 5deg; - rotate: 134deg; - rotate: 89deg; / 步进的计算始终从最小值开始,因此最大值有时未必一定能被选中。比如,random(100, 200, 30)可能返回100130160190;但不会返回200—— 因为从100开始以30为步长递增,并不能恰好到达200。当然,210也不可能出现,因为它已经超出了设定范围。

#### 共享选项

默认情况下,random()函数每调用一次,都会返回一个不同的值。但在某些场景里,我们并不希望如此。比如,假设aspect-ratio还不存在,而我们想通过随机设置宽度和高度来生成一个正方形: div {   width: random(10em, 30em);   height: random(10em, 30em); } / 可能的结果: - width: 14em; height: 15em; - width: 21em; height: 11em; - width: 17em; height: 27em; / 为了解决这个问题,CSS 提供了一种在同一条规则、同一个元素,甚至全局范围内共享随机值的方式。做法是在参数列表最前面加入一个新的参数,用来指定 “共享方式”。

它可以取以下几种不同的值:

##### auto

这是默认值,表示每一个random()实例都会独立生成随机结果。这个参数可以省略不写。 div {   width: random(auto, 100px, 200px);   height: random(auto, 100px, 200px); } / 使用 auto:效果等同于不写共享选项时直接调用 random() 可能的结果: - div.div1 --> width: 125px; height: 198px; - div.div2 --> width: 142px; height: 101px; / ##### 虚线标识符(例如--w

如果传入一个虚线标识符,那么这个随机值会在同一元素的多个属性之间共享,但不会跨元素共享。 div {   width: random(--d, 100px, 200px);   height: random(--d, 100px, 200px); } / 使用虚线标识符:所有 div 都会变成正方形, 因为同一个元素内的属性共享了同一个生成值。 可能的结果: - div.div1 --> width: 150px; height: 150px; - div.div2 --> width: 134px; height: 134px; / 之所以会这样,是因为random()在内部会先生成一个介于01之间的基础随机值,再据此计算最终结果。当多个random()调用使用了同一个虚线标识符时,浏览器会复用这一基础值,于是它们的结果就会彼此关联,即便这种关联从表面上看并不明显。

##### element-shared关键字

它既可以单独使用,也可以与虚线标识符搭配使用。其作用是:在多个元素之间共享随机值;但如果没有额外指定虚线标识符,同一元素内部的不同属性之间并不会共享。 div {   width: random(element-shared, 100px, 200px);   height: random(element-shared, 100px, 200px); } / 单独使用 element-shared:生成的值会在不同元素之间共享, 但同一元素内的不同属性仍然各自独立。 可能的结果: - div.div1 --> width: 150px; height: 134px; - div.div2 --> width: 150px; height: 134px; /div {   width: random(--v element-shared, 100px, 200px);   height: random(--v element-shared, 100px, 200px); } / 同时使用 element-shared 和虚线标识符: 生成的值会在属性之间、元素之间一并共享, 也就是所有地方都得到同一个值。 可能的结果: - div.div1 --> width: 128px; height: 128px; - div.div2 --> width: 128px; height: 128px; / ##### fixed关键字加数字 ID fixed后面可以跟一个数字 ID,用来指定一个固定的全局随机标识。因此,这个值会在全局范围内共享。 div {   width: random(fixed 0.5, 100px, 200px);   height: random(fixed 0.5, 100px, 200px); } / 使用 fixed:生成的值会在所有元素、所有相关属性之间共享。 可能的结果: - div.div1 --> width: 167px; height: 167px; - div.div2 --> width: 167px; height: 167px; / 需要说明的是:这里对共享机制的解释是一个相对简化的版本。如果你想了解更完整、更严谨的定义,建议直接查阅规范原文。

至此,我们已经梳理了random()函数的各种语法形式与共享选项。接下来,就可以继续看看《CSS Values and Units Module Level 5》最新草案中引入的第二个新函数了。

#### random-item()

CSS 中有些属性的取值是离散的,无法用一个连续区间来表达。在这种情况下,random()就显得不那么合适了。我们需要的是另一种函数:它接收一组候选值,然后从中随机选出一个 —— 而这正是random-item()的用途。 random-item()接收一个共享选项以及一系列候选值作为参数,然后从列表中随机挑选并返回其中一个值: div {   display: random-item(--d, block, flex, grid, table);   opacity: random-item(--o, 0.5, 0.6, 0.75, 0.9, 1);   background: random-item(--b, red, #00f, conic-gradient(#fff 0 0)); } / 可能的结果: - display: block; opacity: 0.9; background: #00f; - display: grid; opacity: 0.6; background: red; - display: flex; opacity: 0.75; background: red; / 有一点尤其值得注意:在random-item()中,共享变量并不是可选项,而是必填项。

顺便一提,还有一个小细节,或许有些读者早已知道,但我是这次阅读规范时才注意到的 —— 当然,它很可能源自另一份规范:当某个 “逗号分隔的值列表” 本身要作为 “另一个逗号分隔参数列表中的单个参数” 传入时,CSS 允许使用花括号{}来界定这组值。说白了,这主要是在向函数传递嵌套列表时才会用到。 div {   font-family: random-item({ Times, serif }, { Arial, sans-serif }, monospace); } / 可能的结果: - Times, serif - Arial, sans-serif - monospace /random()一样,如果两个random-item()使用了相同的虚线标识符,并且候选项的数量也相同,那么它们的结果之间就会形成对应关系。比如:

* random-item(--a, 1, 2, 3) * random-item(--a, red, green, blue)

如果第一个函数返回的是2(也就是第二项),那么第二个函数就会返回green(同样是第二项)。这种联动在某些场景下会非常实用,比如你希望不同特征能够成组搭配出现时。

#### 结语

希望这篇文章能带来一些启发,也希望你借此了解了 CSS 即将迎来的random()random-item()函数 —— 如果你正在使用 Safari,其实已经可以提前体验其中一部分了。

这篇文章最后写得比预想中更长一些,不过我依然觉得值得:毕竟,把这些选项逐一讲清楚,并辅以具体示例,才能真正看出它们的潜力与边界。

当然,在生产环境中使用这些函数时,仍然需要认真考虑浏览器兼容性,以及 CSS 缓存、共享机制和性能方面的影响。同时,也不妨多想想它们的实际应用场景 —— 例如随机颜色、随机旋转、随机间距等,这些都能在不借助 JavaScript 的前提下,为页面增添更生动的视觉变化。

也许有人会质疑:把这样的能力直接加入 CSS,真的合适吗?

从架构层面看,它其实是说得通的。因为这本质上是一个布局与呈现层的问题,那么由布局层 —— 也就是 CSS—— 来处理,反而比继续依赖逻辑层的 JavaScript 更顺理成章。

关于本文

译者:@飘飘

作者:@Alvaro Montoro

原文:https://alvaromontoro.com/blog/68092/native-random-values-in-css

这期前端早读课

对你有帮助,帮”赞“一下,

期待下一期,帮”在看” 一下。 阅读原文 跳转微信打开

查看原文 → 發佈: 2026-03-18 09:03:00 收錄: 2026-03-18 12:00:43

🤖 問 AI

針對這篇文章提問,AI 會根據文章內容回答。按 Ctrl+Enter 送出。