Reactコンポーネントの構造
各Reactコンポーネントがどのような外観であるべきか、私の考え
421
13 分。
SST規格は、タブのセマンティクス、アクセシビリティ、および動作ロジックに関する要件を規定しています。
overflow-x: autoを設定する。横スクロールするのはタブ列だけで、ページ全体ではない。パネルの内容は画面幅に合わせてリフローさせる。10–20px。リストが続くことを視覚的に示せるため、装飾的な矢印アイコンは必須ではない。選択中タブのラベルやフォーカスインジケーターは切り取らない。この視覚的な手掛かりはキーボード操作の代わりにはならない。-webkit-overflow-scrolling: touchをスムーズなスクロールの基本要件とはしない。現在のiOSおよびiPadOSでは、このプロパティがなくてもoverflow領域のスクロールが高速化される。iPhoneでは、指定によってスタッキングコンテキストが作られる場合もある。明示的にサポートする旧バージョンがあり、実機検証で必要と判断された場合に限って追加する。選択中タブには、アクセントラインや背景色の変更など、明確な視覚状態を設ける。色だけで状態を区別しない。
タブを選択したとき、キーボードフォーカスが移動したとき、または直接リンクからページを開いたとき、選択中タブが表示範囲に入り、可能な範囲で中央に近づくようにスクロールする。
センタリングはスクロール可能範囲内で行う。コンテナーの端にある最初と最後のタブは、常に正確な中央へ配置できるとは限らない。
LTRレイアウトでは、スクロール内容の先頭を基準に目標値を計算できる。
targetScrollLeft = clamp(tabStart + tabWidth / 2 - viewportWidth / 2, 0, scrollWidth - viewportWidth)
tabStartはスクロール領域の先頭から見たタブの位置を表す。RTLレイアウトでは書字方向とブラウザーごとの横スクロールの違いを考慮し、可能な場合は論理方向を扱うスクロールAPIを使用する。
role="tablist"を設定し、表示される見出しへのaria-labelledby、またはaria-labelでアクセシブルな名前を付ける。role="tab"、一意で安定したid、関連パネルを指すaria-controls="panel-id"を設定する。role="tabpanel"、一意なid、操作元のタブを参照するaria-labelledby="tab-id"を設定する。aria-selected="true"、それ以外のタブはaria-selected="false"にする。未選択のパネルは、たとえばhidden属性で非表示にする。tabindex="0"、それ以外はtabindex="-1"にする。フォーカス可能な内容がないパネルにはtabindex="0"を設定し、キーボード操作で到達できるようにしてもよい。#tab-idのようにURLフラグメントで安全に使用できるようにする。URLで安全な識別子を使うか、ハッシュの読み取り時に一貫してエンコード・デコードする。history.replaceStateは現在の履歴エントリーを更新し、タブを切り替えるたびに「戻る」の履歴を追加しない。アプリケーションは同じイベント処理内でタブ状態を更新し、hashchangeイベントに依存しない。history.pushStateを使い、popstateイベントでタブ状態を同期する。tablist、tab、tabpanelは、同一ページ内でパネルを切り替えるタブにのみ使用する。別ページへの移動には、見た目がタブでもリンクを使用する。Tabキーでタブ列に入ると、選択中タブにフォーカスが移る。次のTabキーでタブリストを抜け、パネル内の内容または次のページ要素に移動する。←と→でタブ間のフォーカスを移動し、端に達したら反対側の端へ移る。RTLでは、キーの方向を視覚的な順序と読み方向に合わせる。HomeとEndで先頭または末尾のタブにフォーカスを移動してもよい。手動アクティベーションでは、フォーカス中のタブをEnterまたはSpaceで選択する。自動アクティベーションでは、フォーカスに合わせて選択状態を切り替える。aria-selected、aria-controlsとaria-labelledbyの関連付け、パネルの表示状態が同期している。replaceStateを使用する場合、タブの切り替えでアドレスは更新されるが、タブごとの履歴エントリーは追加されない。pushStateを使う場合、「戻る」「進む」でURL、選択中タブ、パネルが同期する。prefers-reduced-motion: reduceを有効にしたユーザーの妨げにならない。パネルとARIA属性を関連付けたタブ列:
<div class="tabs__viewport">
<div class="tabs__list" role="tablist" aria-label="ドキュメントのセクション">
<button
id="tab-overview"
type="button"
role="tab"
aria-controls="panel-overview"
aria-selected="true"
tabindex="0"
>
概要
</button>
<button
id="tab-details"
type="button"
role="tab"
aria-controls="panel-details"
aria-selected="false"
tabindex="-1"
>
詳細
</button>
</div>
</div>
<section
id="panel-overview"
role="tabpanel"
aria-labelledby="tab-overview"
tabindex="0"
>
「概要」セクションの内容。
</section>
<section
id="panel-details"
role="tabpanel"
aria-labelledby="tab-details"
tabindex="0"
hidden
>
「詳細」セクションの内容。
</section>一列のスクロール可能なタブ列を作るCSS:
.tabs__viewport {
overflow-x: auto;
padding: 2px;
scroll-behavior: smooth;
}
.tabs__list {
display: flex;
flex-wrap: nowrap;
width: max-content;
min-width: 100%;
}
.tabs__list [role="tab"] {
flex: 0 0 auto;
white-space: nowrap;
}
.tabs__list [role="tab"][aria-selected="true"] {
border-block-end: 2px solid currentColor;
}
.tabs__list [role="tab"]:focus-visible {
outline: 2px solid currentColor;
outline-offset: 2px;
}
@media (max-width: 767px) {
.tabs__viewport {
scrollbar-width: none;
}
.tabs__viewport::-webkit-scrollbar {
display: none;
}
}
@media (prefers-reduced-motion: reduce) {
.tabs__viewport {
scroll-behavior: auto;
}
}モバイルでは、次のタブの一部を見せることで、非表示にしたスクロールバーの代わりにスクロール可能であることを示す。見える幅はコンテナーとラベルに応じて調整し、選択中タブとフォーカスインジケーターは完全に表示する。
メディアクエリーの767pxは例であり、SST-Aの固定要件ではない。プロジェクトのレスポンシブ設計で使用するブレークポイントに置き換える。
タブのセンタリングとURL同期:
const centerTab = (tab) => {
tab.scrollIntoView({
block: 'nearest',
inline: 'center'
})
}
const findTabFromUrl = (tabs) => {
const tabId = window.location.hash.slice(1)
return tabs.find((tab) => tab.id === tabId) || null
}
const updateTabUrl = (tab) => {
window.history.replaceState(null, '', '#' + tab.id)
}初期化時にfindTabFromUrlで見つかったタブと対応するパネルを有効にし、そのタブをcenterTabに渡す。ユーザーがタブを選択したときは、まずaria-selected、roving tabindex、パネルの表示状態を更新し、続けてcenterTabとupdateTabUrlを呼び出す。この例は状態、URL、スクロールの同期を示すもの。キーボード用ハンドラーは上記のルールに従って実装する。
各Reactコンポーネントがどのような外観であるべきか、私の考え
421
13 分。
SSF-U規格は、フルスクリーン表示のセマンティクス、アクセシビリティ、および動作ロジックに関する要件を規定しています
248
3 分。
SSA規格は、アコーディオンのセマンティクス、アクセシビリティ、および動作ロジックに関する要件を定めています
258
4 分。
ウェブデザインにおける致命的なミスの分析。スライダー、自動再生、重いページがコンバージョン率やGoogleでの検索順位を低下させる理由
232
2 分。
SSP規格は、ページネーションのセマンティクス、アクセシビリティ、および動作ロジックに関する要件を規定しています
240
3 分。
SSPS標準は、プロジェクト内のファイルおよびフォルダの構造と命名に関する要件を規定しています
345
3 分。