アクセシビリティ公開 約8分

入力中のグループを示す:focus-withinと入力欄の枠を使い分ける

入力欄が多い画面で、今どのまとまりを操作しているか示したい人へ。focus-withinで親の枠を変え、子のfocus-visibleも残す完成例を作ります。グループ内と外への移動を分けて確認します。

この記事の目次
  1. 親の枠は「どの欄か」の代わりにはならない
  2. 二つのfieldsetを持つ見本を保存する
  3. 枠が出ないときと、広すぎるときは調べる場所が違う
  4. 入力中と、選択済み・エラーを分けて設計する
  5. 同じ親の中で移り、外へ出た結果を照合する

長い入力画面では、一つの欄に枠が付いていても、それが参加者の情報なのか、連絡担当の情報なのか見失うことがあります。入力欄自身の印に加え、操作しているまとまりを囲む枠を用意すると、二つの範囲を同時に確認できます。

HTMLのlabelとCSSのセレクターが分かる人向けです。架空の工作体験の入力見本を、一枚のHTMLに作ります。送信・保存・入力検証は付けず、二つのまとまりを移動したときの表示に絞ります。個別の枠を戻す基本はフォーカス表示の記事で確認できます。

親の枠は「どの欄か」の代わりにはならない

たとえば「参加者」の中に名前と作品名がある場合、親だけを強調すると、どちらへ文字が入るかは区別できません。外枠はまとまり、内側の枠は実際の操作対象という役割にします。外枠を付けたことを理由に、入力欄のoutlineを消さないでください。

:focus-withinは、要素自身か、その子孫にフォーカスがある場合に一致する疑似クラスです。MDNの説明にある親子関係を利用するので、JavaScriptで親へクラスを付け外しする必要はありません。入力欄が親の中にあることが条件です。

親へ:focusを書くのとは異なります。通常のfieldsetはTabの移動先ではないため、子に入力してもfieldset自身のfocusには一致しません。見た目のためにfieldsetへtabindexを足すと、入力しない箱にも停止位置が増えます。今回は既存の入力欄だけを順にたどる構造を保ちます。

名前から作品名へ移っても参加者の外枠は残り、入力欄の枠だけが移る比較図

二つのfieldsetを持つ見本を保存する

次をfocus.htmlとして保存し、ブラウザーで開きます。個人情報は不要なので、入力する場合も架空の文字を使ってください。fieldsetは関連する欄のまとまり、legendはそのまとまりの名前です。fieldsetの資料と合わせ、見た目だけのdivと役割を区別します。

<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>工作体験の入力見本</title>
<style>
* { box-sizing: border-box; }
body { margin: 16px; font-family: sans-serif; line-height: 1.8; }
main { max-width: 560px; margin: auto; }
fieldset { min-width: 0; margin: 20px 0; padding: 20px;
  border: 3px solid #777; }
fieldset:focus-within { border-color: #174ea6; background: #edf4ff; }
legend { font-weight: bold; }
label, input { display: block; }
input { width: 100%; font: inherit; margin-bottom: 16px; }
input:focus-visible, a:focus-visible {
  outline: 3px solid #174ea6; outline-offset: 3px;
}
</style>
</head>
<body><main>
<h1>工作体験の入力見本</h1>
<p>練習用です。入力内容を保存・送信しません。</p>
<fieldset>
  <legend>参加者</legend>
  <label for="participant">参加者名</label>
  <input id="participant" type="text">
  <label for="work">作りたい作品</label>
  <input id="work" type="text">
</fieldset>
<fieldset>
  <legend>連絡担当</legend>
  <label for="contact">担当者名</label>
  <input id="contact" type="text">
</fieldset>
<a href="#note">この見本について</a>
<p id="note">枠の変化を確認するための架空の入力画面です。</p>
</main></body>
</html>

幅が変わっても枠線の太さは3pxのままです。操作中だけ太くすると、入力欄の場所まで動く可能性があるため、ここでは色と背景だけを変えています。青い背景だけで判断せず、legendの名前と個別の操作枠も読み取ります。

この例にはアニメーションがありません。フォーカスした瞬間の点滅や時間で消える装飾も加えていないので、入力を止めて説明を読む間も同じ範囲が残ります。実際のサイトへ移すときは、既存の背景色の上でも枠が見えるかを改めて確かめます。

枠が出ないときと、広すぎるときは調べる場所が違う

第一の失敗は、CSSをfieldset:focusへ変えることです。Tabで参加者名へ入っても外枠が変わりません。子のinputはフォーカスされていますが、fieldset自身へ移っていないのが原因です。focus-withinへ戻し、名前の入力中に参加者だけが青い枠になるか再確認します。

第二の失敗は、main:focus-withinでページ全体を囲むことです。入力を終えて説明リンクへ移ってもmainの中なので強調が残ります。入力中のグループを示すという目的に対し、選んだ親が広すぎます。完成例のfieldsetへ戻し、説明リンクでは両方の外枠が通常色になることを確認します。

逆に、見た目では近くにある欄がfieldsetの閉じタグの外にあれば、その欄への入力は親の強調を起こしません。CSSの値を強くする前に、開発者ツールでDOM上の親子関係を見ます。余白で近付けることと、HTMLで内側へ入れることは別です。

入力中と、選択済み・エラーを分けて設計する

focus-withinは「入力が正しい」「保存できた」という意味ではありません。文字を入力してから外へ移ると強調が消えますが、値は残ります。エラーの案内や選択済みの状態まで、この疑似クラスに任せる設計にはしません。

また、まとまりを入れ子にすれば、内側のinputにフォーカスがある間、外側の祖先にも一致します。必ず一個の親にだけ一致する仕組みではありません。今回のような同じ階層のfieldset二つなら、片方だけが強調される条件を作れます。

単一の入力欄だけの画面なら、外枠を増やしても情報が増えない場合があります。まず個別のフォーカス表示とlabelを整え、まとまりの名前を見失う場面があるときに親の表示を加えます。読み上げへのグループ名の伝わり方はCSSとは別なので、fieldsetとlegendを残して使用環境で確認してください。

同じ親の中で移り、外へ出た結果を照合する

10〜15分を目安に、Tabで参加者名、作品名、担当者名、説明リンクへ進みます。次の四行を完成条件にします。順番が異なる場合はOSやブラウザーのキーボード設定も確認します。

移動先 外枠 個別の表示
参加者名 参加者だけ強調 参加者名に枠
作りたい作品 参加者の強調が続く 作品名へ枠が移る
担当者名 連絡担当だけ強調 担当者名に枠
説明リンク どちらも通常色 リンクに枠

Shift+Tabで戻った場合も同じ対応になるか確認します。幅320pxでは入力欄と外枠の右端が切れず、legendが読めることも調べます。アクセシビリティの無料レッスンでほかの部品を点検するときも、個別の位置とまとまりを別々に記録できます。名前から作品名へ移ったとき、外側は残り内側だけが移れば、二つの役割を見分けられています。

TRY A LESSON

記事の内容を、課題で確かめる

操作とコントラストを確かめる練習 →

アクセシビリティの学習内容 →

記事についてのお問い合わせ

記載内容へのご質問や訂正のご連絡は、hello@junkbranding.comまでお願いします。

← 記事一覧に戻る