Edited at

CSS で乱数を使えるようにする

CSS だけで乱数を使うことはできません。仕様上、 random(min, max); のような関数もしくは類似する機能はないため、 CSS 以外の技術に頼らざるを得ないのが現状です。

大抵の場合は下記のいずれかでしょう。


  • Sass のような CSS プリプロセッサ

  • React にあるような CSS in JS

  • サーバサイドレンダリング

もちろん、 JavaScript を使えば Pure CSS でも乱数を擬似的に使うことは可能です。今回はこれ。

ただ、 Pure CSS で開発するケースは極めて稀でしょうから、実用性はありません。


デモ

Reload ボタンを押すごとに要素のスタイルが変化すれば成功です。


See the Pen
CSS Random Variable
by mimonelu (@mimonelu)
on CodePen.


コード

1 ファイルに収めてみましたが、 link タグによる外部スタイルシートでも問題なく動作します。

<style>

p {
background-color: rgb(var(--random_128_255), var(--random_128_255), var(--random_128_255));
color: #var(--random_0_8)var(--random_0_8)var(--random_0_8);
font-size: var(--random_10_30)px;
padding: 16px;
}
p::before {
content: "var(--random_1_6)";
}

</style>
<script>

;Array.prototype.slice.call(document.styleSheets).forEach(function (styleSheet) {
Array.prototype.slice.call(styleSheet.cssRules).forEach(function (cssRule) {
cssRule.style.cssText = cssRule.style.cssText.replace(/var\(\-\-random_(\d+)_(\d+)\)/g, function (a, b, c) {
var min = parseInt(b, 10);
var max = parseInt(c, 10);
return Math.floor(Math.random() * (max - min + 1)) + min;
});
});
});

</script>
<p> is random number.</p>


説明

要するに var(--random_MIN_MAX) という変数(のふりをした文字列)を乱数に置換しているだけです。

本来は random(MIN, MAX) という関数形式にしたかったのですが、 document.styleSheets には「適用されたスタイル」すなわち「 Valid なスタイル」のみ格納されるらしく、 random() などという存在しない関数は Invalid となり無視されてしまうため、変数という形になりました。

つまり存在しない変数は Valid とみなされるようです。とは言え、 color: #var(--random_0_9)var(--random_0_8)var(--random_0_8); こんなのが Valid だとはとても思えませんが…実際存在する変数に置き換えても動作しないし🤔

しかしまぁ、関数形式だと px のような単位との組み合わせが難しくなるため、結果的には変数の方が良かったかなと。


おわりに

何となく勢いで作ってしまったので、よりベターなアプローチがあるかどうかは調べていません。需要ないし。

しかもこれプロパティだけでしか使えないんですよね。 :nth-child(random(1, 3)) みたいなこともしたいんですが、思い付かず。

ちなみに、 CSS 標準に乱数生成ルールを組み込むことについての難しさは このあたり が参考になると思います。