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 星場,使用隨機放置的圓形、發光效果和四角星
我們將從為每顆星星創建一個 HTML 元素開始。然后,用任意大小的白色圓形來繪制天空并設置星星的樣式。將星星設置為固定定位將使其易于隨機放置。
<html>
<body>
<div class="star"></div>
<div class="star"></div>
…
<div class="star"></div>
</body>
</html>body {
background-color: black;
}
.star {
background-color: white;
border-radius: 50%;
aspect-ratio: 1/1;
width: 3px;
position: fixed;
}現在,我們將通過將 top 和 left 屬性設置為隨機值來分布星星,在這種情況下,top 為 0-100%(Y 軸),left 為另一個隨機值(X 軸)。默認情況下,每個 random() 函數將使用不同的隨機基數生成不同的隨機值,該隨機基數由均勻分布生成。
.star {
background-color: white;
border-radius: 50%;
aspect-ratio: 1/1;
width: 3px;
position: fixed;
top: random(0%, 100%);
left: random(0%, 100%);
}
為了更動態的效果,也讓“星星”的大小隨機。
.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 為增量,以獲得更好的數字分布,從而提供更多變化。
隨機大小的圓形作為星星
我們可以通過添加一些特殊效果,如使用分層陰影和混合效果為星星添加微妙的發光效果,來進一步發揮這個想法。
.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(0px0pxcalc(var(--star-size) * 0.5) oklch(0.70.2random(0, 100)))
drop-shadow(0px0pxcalc(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 將在所有應用它的元素中共享給定屬性的隨機值。
在星場示例中看到這一點工作的一種方法是添加一些帶有簡單圖形的四角星。
.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 值為所有元素生成一個隨機值,用于該屬性。這使得所有四角星都以相同的隨機角度旋轉。
以下是你可以嘗試的星場示例的完整版本:https://codepen.io/jdatapple/pen/YPyELeV?editors=1100
隨機放置的矩形
還有許多其他方法可以利用 random()。基于星場示例的一些概念,你可以探索使用 random() 與布局工具(如 grid)。
隨機放置和隨機顏色的矩形
在這個變體示例中,網頁區域被平均分為 100 行和 100 列。然后,隨機顏色的矩形在網格中隨機定位:
.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() 的瀏覽器中查看最終結果:https://codepen.io/ntim/pen/dPYGJxj
照片堆疊
另一個利用 random() 的示例是創建隨機放置和定向的照片堆疊,看起來像它們被扔在彼此上面。你可以花很多時間設置所有照片,或者讓計算機每次頁面加載時程序生成它。
圖片
沙漠景觀照片的堆疊,圖像隨機旋轉并隨機偏移放置
.stack img {
width: 100%;
grid-column: 1;
grid-row: 1;
border: 10px solid hsl(0, 100%, 100%);
box-shadow: 10px10px40pxhsl(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%);
}不僅如此,將隨機性包含在交互性中也很簡單。為圖像的懸停狀態添加隨機平移增加了趣味性:
.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)));
}幸運轉盤
random() 函數甚至可以用來創建需要不可預測結果的交互元素。幸運轉盤示例完美地展示了這一點。
圖片
隨機旋轉的轉盤,切成 20 片,每隔一片放置表情符號,以及一個綠色的旋轉按鈕
當點擊“SPIN”按鈕時,@keyframe 動畫使用 random() 生成一個旋轉值,該值設置轉盤何時以及在哪里停止。這個示例突顯了現代 CSS 中不斷增長的可用功能,在樣式表中定義了所有交互性、隨機性和動畫。
你可以在這里看到演示:https://codepen.io/ntim/pen/WbQrMow
一個方便的隨機性參考
根據你的需求,有各種各樣的方法可以使用 random(),也有不同的方法可以在元素之間共享隨機性。
最大隨機性
兩個屬性獲得不同的值,而且每個元素也不同,所以你會得到很多隨機矩形。
.random-rect {
width: random(100px, 200px);
height: random(100px, 200px);
}在元素內按名稱共享
使用標識符,兩個屬性獲得相同的值,但每個元素仍然不同,所以你會得到很多隨機正方形。
.random-square {
width: random(--foo, 100px, 200px);
height: random(--foo, 100px, 200px);
}在屬性內共享元素
使用 element-shared,兩個屬性獲得不同的值,但它們被所有元素共享,所以你會得到很多相同大小的單個隨機大小的矩形。
.shared-random-rect {
width: random(element-shared, 100px, 200px);
height: random(element-shared, 100px, 200px);
}全局按名稱共享
使用命名標識符和 element-shared 意味著兩個屬性獲得相同的值,每個元素都共享隨機值,所以你會得到很多相同大小的單個隨機大小的正方形。
.shared-random-squares {
width: random(--foo element-shared, 100px, 200px);
height: random(--foo element-shared, 100px, 200px);
}試試并告訴我們結果如何
你可以在 Safari Technology Preview 中今天嘗試 random() 函數!然而,重要的是要指出,CSS 工作組正在討論規范,有幾個開放的問題關于這種方法是否最好地滿足開發者的需求。
雖然上述示例展示了令人興奮的可能性,但我們正在積極征求網絡開發社區的意見,以幫助塑造最終方向,你可以幫忙。如果你在 Safari Technology Preview 中嘗試了 random(),我們將非常樂意聽到你的體驗。哪些方面做得很好?哪些方面感覺不自然?共享值的表達方式是否有意義?是否有缺失的使用案例?或者對 element-shared 的名稱有更好的建議?你的反饋將直接影響此功能從當前形式向前發展的方式。這是一個讓你幫助塑造 CSS 的機會——試試看,并告訴我們你的想法。
你可以在 Bluesky / Mastodon 上與我 Jon Davis 分享你的反饋,或者我們的其他布道者——Jen Simmons,在 Bluesky / Front-End Social 上,或者 Saron Yitbarek,在 BlueSky上。你也可以關注 WebKit LinkedIn。如果你發現錯誤或問題,請提交 WebKit 錯誤報告。
原文地址:https://webkit.org/blog/17285/rolling-the-dice-with-css-random/作者:Jon Davis, Jen Simmons, and Tim Nguyen






























