LoginSignup
2
1

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-08-17

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 標準に乱数生成ルールを組み込むことについての難しさは このあたり が参考になると思います。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1