ボタン
component「保存」「キャンセル」など、操作のきっかけになる最も基本的なパーツです。重要度や場面に応じて色・形・大きさを選べます。
Variant × Theme size = medium / state = enable
| solid | outline | subtle | ghost | |
|---|---|---|---|---|
| primary | ||||
| secondary | ||||
| neutral | ||||
| negative |
size
primary / solid
state
primary / solid / medium
prefix / suffix
slot は 24×24 / gap 8 — アイコン単体は .icon-btn を使う
prefix slot
suffix slot
プロパティ
| prop | values | description |
|---|---|---|
thema |
primary · secondary · neutral · negative |
ボタンの色彩テーマ。Semantic Token の同名ロールにマップ。 |
size |
sm · md · lg · xl |
高さ・パディング・フォントサイズ・行間がまとめて切り替わる。 |
variant |
solid · outline · subtle · ghost |
背景・枠線・テキスト色の組み合わせを変える。 |
state |
enable · :hover · :focus-visible · [data-loading] · :disabled |
CSS の擬似クラスと data-loading/disabled 属性で表現。 |
icon slot |
prefix · suffix | SVG を <button> 直下に置けば 24×24 スロットになる。アイコン単体のボタンは .icon-btn を使う。 |
機能
このコンポーネントの用途
ユーザーのアクション(送信・保存・削除など)を引き起こす主操作要素。
ページ遷移そのものが目的なら button ではなく link を使う。
使用法
推奨される使い方と、やりがちな NG パターン
OK
- ✓主要アクションは 1 画面に btn-primary 1 つ。副次は btn-neutral / btn-ghost。
- ✓破壊的操作(削除など)は btn-negative。
- ✓非同期処理中は data-loading を付け二重送信を防ぐ。
NG
- ✕遷移リンクを btn でスタイルしない → href のナビゲーションは link。
- ✕1 画面に btn-primary を複数置かない → 主従が伝わらない。副次は neutral/ghost。
- ✕色を #hex 直書きしない → btn-primary 等のクラスで色は決まる。
- ✕アイコンだけのボタンに btn を使わない → アイコン単体は icon-btn(アイコンボタン)に aria-label を付ける。
- ✕リストの各行に「削除」等の同ラベル btn を並べたまま放置しない
破壊的操作は btn-negative
色でも危険を伝える
削除など取り消せない操作は btn-negative。色で危険を示す。
削除を primary にすると通常操作と区別できず、誤操作を招く。
ページ遷移は link(btn でスタイルしない)
要素の役割を合わせる
遷移を btn でスタイルしない。役割が「ボタン」になり遷移手段が壊れる。
NG パターン — ボタンサイズの混在
ボタンを並べる時の注意点並ぶボタンは同じサイズで揃え、ヒエラルキーは variant(solid / outline)で表現する。
サイズが異なるボタンを隣り合わせで使用することは避けてください。
NG パターン — solid ボタンの並列
主アクション 1 つだけを solid にして強調し、副アクションは neutral / subtle で抑える。
塗りつぶしの色が異なる場合、2 つの solid ボタンを隣り合わせで使用することは避けてください。
期待される配慮
Presentation / Adaptability / Interaction / Assistive Technology
ラベルは可視テキスト、アイコンのみは aria-label。主操作は 1 画面 1 つ(primary)、破壊的操作は negative で色でも示す。
サイズは sm32 / md40 / lg48 / xl72。lg 以上で 44px(AAA ターゲット)。文字は rem で拡大に追従。
Tab で到達、Enter/Space で実行。フォーカスリング(info/600・2px・offset 2px)が出る。
ネイティブ <button> で役割・名前・状態が確立。名前は可視テキスト/aria-label、非同期中は data-loading、無効は disabled で伝える。
DS が担保する機能
追加実装なしで満たされる
- ✓ネイティブ
<button>ベース — 役割・名前・状態が標準で確立 - ✓キーボードフォーカスリング(
:focus-visible・info/600・2px・offset 2px) - ✓各テーマの文字色は背景に対しコントラストを確保
- ✓
lg(48px)以上でターゲット拡張(WCAG 2.5.5)を満たす
実装時の必須対応
プロダクト側で担保する
- !アイコンのみのボタンに
aria-label(可視テキストと重複する label は付けない) - !同じ操作が並ぶ時は対象を含めてアクセシブルネームを一意化する
- !ページ遷移には使わない →
link。主操作は 1 画面 1 つ、破壊的操作は negative - !非同期処理中は
data-loadingで二重送信を防ぐ
テスト方法
キーボード / スクリーンリーダー / 自動チェック
| キー | 動作 |
|---|---|
| Tab / Shift+Tab | 各ボタンへ移動(フォーカスリング表示) |
| Enter / Space | 操作を実行する |
- SRボタン名(可視テキスト or
aria-label)が読まれ、並ぶ同操作の対象が区別できる - 自動axe / Lighthouse で name・コントラスト・ターゲットサイズを確認
同じラベルが並ぶ時は対象を含めて一意化
達成基準:WCAG 2.4.4 リンクの目的(コンテキスト内)- りんご
- みかん
- ぶどう
対象を .sr-only で後置。見た目は「削除」のまま、名前は一意。
読み上げ名: 削除(りんご)/ 削除(みかん)/ 削除(ぶどう)
<button class="btn …">削除<span class="sr-only">(りんご)</span></button>
- りんご
- みかん
- ぶどう
全ボタンが「削除」。どの行の削除か区別できない。
読み上げ名: 削除 / 削除 / 削除
<button class="btn …">削除</button> <!-- 各行すべて同じ名前 -->
可視テキストと重複する aria-label は付けない
達成基準:WCAG 2.5.3 ラベルを含む名前
可視テキストがそのままアクセシブルネームになる。aria-label は不要。
<button class="btn …">保存</button>
可視テキストと同じ aria-label は冗長。翻訳ズレの温床にもなる。
<button class="btn …" aria-label="保存">保存</button> <!-- 可視テキストと重複 -->
キーボードフォーカスは必ず可視化される
達成基準:WCAG 2.4.7 フォーカスの可視化 / 2.4.13 フォーカスの外観Tab キーで順に移動すると、info/600 のフォーカスリング(2px / offset 2px)が出ます。マウスクリックでは出ません(:focus-visible)。