ボタングループ
複数ボタンを罫線を共有して連結したセグメント操作。上段は単一選択(左/中央/右揃え)、下段は複数トグル(太字/斜体/下線)の2パターンを見せる。
プレビュー
クリック
操作クリック/タップで動きます。
仕様書
- 向く場面
- 左/中央/右揃えなど排他の選択
- 太字/斜体など独立したオン/オフの並び
- ツールバーで関連操作を連結して見せる
- 避ける場面
- 無関係な操作を見た目だけ連結する
- 選択肢が多く横幅を超える
- 単一選択と複数トグルを同じ見た目で混在させ区別できない
- 構成要素
- グループ枠
- ボタン
- 仕切り線
- 選択面
- 持っている状態
- 通常
- ホバー
- フォーカス
- 押下中
- キーボード
単一選択: Tab でグループへ・←→↑↓ で移動と同時に選択・Home/End。複数トグル: Tab で各ボタンへ・Enter/Space で切替
- 支援技術
単一選択は role=radiogroup/radio+aria-checked とローミング tabindex、複数は aria-pressed(APG Radio Group/Toggle Button)。各 aria-label。選択は塗りで示す
- 動き
背景・文字色 0.15s。reduced-motion で無効
デザインの要点
- 単一選択は radiogroup+ローミング tabindex、複数トグルは aria-pressed と、見た目が同じでも役割で ARIA を分ける。読み上げで「3 つのうち 1 つ」か「オン/オフ」かが変わる
- 仕切りは先頭以外の左辺に 1px だけ引く。各ボタンに border を持たせると隣接部が 2px になり、外枠と太さが揃わない
- 選択面は藍の塗り+白文字。枠線や下線だけの選択表示は、グループが小さいほど見落とす
- focus-visible は outline-offset を負にして内側に描く。外側に出すと overflow:hidden の角丸で切れる
実装メモ
連結の罫線は「先頭以外のボタンの左辺に1pxだけ」引き、外枠はグループ側の border と overflow:hidden の角丸で処理しています。単一選択は role=radiogroup + ローミング tabindex(矢印キーで移動と同時に選択、Tabはグループ単位で抜ける)、複数トグルは各ボタンの aria-pressed を独立して切り替えます。選択状態はどちらも同じ藍のアクセント面で表しています。
コード(コピーして使えます)
<div class="stage" id="stage">
<div class="bg-block">
<p class="bg-label">配置(単一選択)</p>
<div class="bg-group" id="alignGroup" role="radiogroup" aria-label="テキストの配置">
<button class="bg-btn" role="radio" aria-checked="true" tabindex="0" data-val="left" aria-label="左揃え">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<line x1="3" y1="4" x2="13" y2="4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>
<line x1="3" y1="8" x2="9" y2="8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>
<line x1="3" y1="12" x2="11" y2="12" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>
</svg>
</button>
<button class="bg-btn" role="radio" aria-checked="false" tabindex="-1" data-val="center" aria-label="中央揃え">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<line x1="3" y1="4" x2="13" y2="4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>
<line x1="5" y1="8" x2="11" y2="8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>
<line x1="4" y1="12" x2="12" y2="12" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>
</svg>
</button>
<button class="bg-btn" role="radio" aria-checked="false" tabindex="-1" data-val="right" aria-label="右揃え">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<line x1="3" y1="4" x2="13" y2="4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>
<line x1="7" y1="8" x2="13" y2="8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>
<line x1="5" y1="12" x2="13" y2="12" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>
</svg>
</button>
</div>
</div>
<div class="bg-block">
<p class="bg-label">書式(複数トグル)</p>
<div class="bg-group" id="styleGroup" role="group" aria-label="文字の書式">
<button class="bg-btn bg-btn--wide" aria-pressed="false" data-val="bold" aria-label="太字">
<span class="bg-glyph bg-glyph--bold">B</span>
</button>
<button class="bg-btn bg-btn--wide" aria-pressed="false" data-val="italic" aria-label="斜体">
<span class="bg-glyph bg-glyph--italic">I</span>
</button>
<button class="bg-btn bg-btn--wide" aria-pressed="false" data-val="underline" aria-label="下線">
<span class="bg-glyph bg-glyph--underline">U</span>
</button>
</div>
</div>
</div>