1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CSSのrandom関数でおみくじを作った

1
Posted at

はじめに

Safari 26.2からCSSのrandom()関数が使えるようになっていますが、2026年10月20日にリリースされたChrome 156でも使えるようになりました。
せっかく使えるようになったので、何か簡単なものを作ってみようと思い、今回はおみくじを作ってみることにしました。

なお、random()はFirefoxでは現時点(2026年10月31日)で未対応のようです。Safari 26.2以降、またはChrome 156以降でご覧ください。

成果物

See the Pen Omikuji by Makoto Ogata (@makoto-ogata) on CodePen.

コード

<div class="wrap">
  <h1>おみくじ</h1>
  <input type="checkbox" id="draw">
  <label for="draw">くじを引く</label>
  <div class="window"></div>
  <p class="note">再読み込みでもう一度引けます</p>

  <p class="unsupported">このブラウザは CSS の random() に未対応です</p>
</div>
.wrap {
  display: grid;
  place-items: center;
}

input {
  display: none;
}

label {
  display: inline-block;
  font-size: 20px;
  padding: 8px 24px;
  border: 1px solid #888;
  border-radius: 4px;
  background: #eee;
  cursor: pointer;
}

.window,
.note {
  display: none;
}

.window {
  height: 1.5em;
  line-height: 1.5em;
  overflow: hidden;
  font-size: 64px;
  font-weight: bold;
  margin: 24px auto;
}

.window::before {
  display: block;
  white-space: pre;
  content: "大吉\A中吉\A小吉\A吉\A末吉\A凶";
  translate: 0 random(-7.5em, 0em, 1.5em);
}

input:checked ~ label {
  display: none;
}

input:checked ~ .window,
input:checked ~ .note {
  display: block;
}

.unsupported {
  display: none;
  color: #c00;
}

@supports not (width: random(0px, 1px, 1px)) {
  .unsupported {
    display: block;
  }
}

解説

全体の仕組み

  1. 「くじを引く」ボタンの正体は<label>で、クリックすると隠しているチェックボックスがオンになります。
  2. チェックが入ると、input:checked ~ ...のセレクタでボタンが消え、結果表示用の.windowが現れます(.windowは最初は非表示です)。
  3. 運勢の文字列はHTMLには書かず、.window::beforeのcontentに\A(改行)で区切って縦に並べています。改行を効かせるためにwhite-space: preを指定しています。
結果
大吉
中吉
小吉
吉
末吉
凶
  1. .windowの高さは1行分(1.5em)で、overflow: hiddenによりはみ出した部分は見えません。つまり、窓から1行だけ覗いているイメージです。
  2. translateで縦に並んだ文字列を上にずらし、窓から見える運勢を切り替えています。

random()の使い方

translate: 0 random(-7.5em, 0em, 1.5em);

random()の引数はrandom(最小値, 最大値, 刻み幅)です。今回は次のように指定しています。

  • 最小値: -7.5em
  • 最大値: 0em
  • 刻み幅: 1.5em

第3引数の刻み幅を指定すると、最小値から刻み幅ずつ進んだ値の中から選ばれます。そのため、連続した値ではなく、次の6通りのどれかになります。1.5emは窓の高さ(1行分)と同じなので、ずれた先でも文字がちょうど窓にはまります。

選ばれる値 見える運勢
0em 大吉
-1.5em 中吉
-3em 小吉
-4.5em 吉
-6em 末吉
-7.5em 凶

刻み幅を省略すると、-7.5emから0emの間のあらゆる値になり、文字が窓の途中で見切れてしまいます。また、6通りはすべて同じ確率(1/6)で選ばれます。本物のおみくじのように、大吉だけ出にくくするといった重み付けはできません。

なお、random()は既定では呼び出しごとに別の値になります。値を共有したい場合は<random-key>を第1引数に渡して制御できますが、今回は1か所でしか使っていないため指定していません。

未対応ブラウザ向けの表示

@supports not (width: random(0px, 1px, 1px)) {
  .unsupported {
    display: block;
  }
}

@supportsでrandom()が使えるかを判定し、未対応のブラウザでだけ「未対応です」というメッセージを表示しています。random()が使えるブラウザでは、このメッセージは非表示のままです。

補足

  • 本来は、リストから1つ選ぶrandom-item()のほうがおみくじには向いています。ただ、Chrome 156ではまだ使えないようなので、今回はrandom()とtranslateの組み合わせで実現しました。
  • 今回はデモなので、チェックボックスをdisplay: noneで隠しています。この方法だとキーボードで操作できないため、実用する場合は<button>を使うか、視覚的にだけ隠す方法を検討してください。

参考

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?