回復薬、ランタン、古い鍵。ひとつだけ持っていくなら、どれにしますか。

今回は小さな選択部品を作りました。名前は Pocket Choice。携帯ゲームの道具選びのような見た目で、選んだカードに「装備中」の札が付きます。古い鍵だけ、使える場所が分からないまま候補にいます。

UI Labの2作目。前回はネオンを光らせましたが、今回は淡い紙色とくすんだ緑、ドットのアイコンにしてみました。

ひとつ選んでみる

大きな画面で試す / ソースをダウンロード

カード全体をクリック・タップできます。キーボードならTabで選択肢に入り、矢印キーで選び直せます。スマホ幅では縦に並びます。選択内容の送信や保存は、このデモには入れていません。

選ぶ仕組みは、普通のラジオボタン

中身は同じnameを持つinput type="radio"です。ひとつ選ぶとほかの選択が外れる処理は、HTML標準の動作を使っています。選択用のJavaScriptは書いていません。

<label class="pc-option">
  <input type="radio" name="pocket" value="potion" checked>
  <span class="pc-card">
    <!-- ここに道具のSVGと説明文 -->
    <strong>回復薬</strong>
    <span class="pc-badge" aria-hidden="true">装備中</span>
  </span>
</label>

上は構造を短くした例です。実際のソースではfieldsetとlegendで選択肢をまとめています。同じページに別の選択部品を置くときは、グループごとにnameを分けます。

ラジオグループの基本動作はMDNの説明も参考になります。

選んだ道具に、装備中の札を付ける

CSSでは、選択されたinputの直後にあるカードを変えています。

.pc-option input:checked + .pc-card {
  background: var(--pc-selected);
  box-shadow: inset 0 0 0 3px var(--pc-paper), 4px 4px 0 var(--pc-ink);
}
.pc-option input:checked + .pc-card .pc-badge {
  visibility: visible;
}

色だけでなく札も出すと、「どれを選んでいるか」が見た目で分かります。札は絶対配置にして、選ぶたびにカードの高さが動かないようにしました。アイコンは16×16の座標で描いた自作SVGです。

今回はアニメーションを入れていません。小さな道具が並ぶ感じと、紙の札がカードの下にはみ出す見た目を楽しむ部品にしました。

キーボードの入口を残す

inputをdisplay: noneにはせず、見た目だけ小さく隠しています。キーボードで操作したときは、選択状態とは別に点線のフォーカス枠が出ます。

.pc-option input:focus-visible + .pc-card {
  outline: 3px dashed var(--pc-ink);
  outline-offset: 7px;
}

「装備中」の札は装飾として読み上げから外し、選択状態は本来のradioに任せています。ラベルには道具名と説明文が入ります。

自分のサイトで使うなら

ZIPのindex.htmlを開けば試せます。部品だけ使うときはfieldset.pc-groupと、CSSの.pc-で始まるルール・色の変数・画面幅別のルールを持っていきます。詳しい範囲はREADMEにまとめました。

  • 色は--pc-ink、--pc-paper、--pc-accent、--pc-selectedで変更。
  • 文言とvalueを変えれば、ゲームの装備選びやテーマ選択にも使えます。
  • フォームに組み込んだ場合、選択値はnew FormData(form).get('pocket')で取得できます。

同梱のdemo.jsは、記事の中に埋め込んだときにサイトへのリンクを隠すためだけのものです。部品の選択操作には不要です。

MIT Licenseで、商用利用・改変OK。再配布時は同梱のLICENSE.txtを残してください。まずは、いつもの選択肢を少しだけ冒険の持ち物に。