代表的な面接トピック

フロントエンド面接:CSSのscroll-target-groupを使ってアクセシブルなスクロールマーカーを構築するには?

フロントエンド難しい
Offer.cc 編集チーム公開日 更新日

質問

長い記事ページに目次、横スクロールカルーセル、および現在のセクションインジケーターが必要です。アンカー、フォーカス、スクロール状態、および非対応ブラウザの使いやすさを維持するために、CSSのscroll-target-groupをどのように評価しますか?

プロンプトとコンテキスト

ページには記事のセクションまたはカルーセルアイテムへのリンクがあり、スクロール中に現在のターゲットを強調表示する必要があります。CSSのscroll-target-groupは、既存のナビゲーションコンテナをスクロールマーカーグループとして宣言し、フラグメントターゲットと表示コンテンツを接続できます。IntersectionObserver、従来のアンカー、scroll-marker-groupとの境界を説明した上で、プログレッシブエンハンスメントを設計してください。

面接官が評価するポイント

面接官は、視覚的な状態が追加される前に機能する本物のリンクがあるかを見ています。優れた回答は、スクロール位置、フォーカス位置、カレントアイテムのスタイリングを明確に区別し、重複ターゲット、動的コンテンツ、横スクロール、視覚効果の抑制(reduced motion)を処理し、実験的プロパティが使用できない場合のフォールバックを説明します。単一のCSS宣言だけでは、操作可能なナビゲーションシステムを実証したことにはなりません。

回答前に確認すべき質問

ナビゲーションターゲットは何ですか?

各リンクが安定したセクションID、カルーセルカード、または仮想リストアイテムのいずれをターゲットにしているかを確認します。ターゲットはブラウザからアドレス指定可能であり、リストが並べ替えられてもその意味を維持する必要があります。

「現在(current)」はどのように定義されますか?

ビューポートに入ること、しきい値を超えること、フォーカスを受け取ること、または最後にクリックされたアイテムであることのいずれを意味するのかを明確にします。スクロール状態とフォーカス状態は異なる場合があるため、単一のカラールールで両方を表現することはできません。

サポートと代替手段

対象ブラウザ、スクリーンリーダー、キーボードの要件をリストアップします。scroll-target-groupは実験的です。従来のアンカーと必要な監視ロジックは、依然として独立して動作する必要があります。

30秒の回答フレームワーク

「私はまずセマンティックなナビゲーションと安定したアンカーを使用して基本的なジャンプを実現し、次にナビゲーションコンテナをscroll-target-groupとして宣言して、ターゲットがビューポートに入ったときにカレントスタイルを受け取れるようにします。スクロールマーカーはフォーカスを管理しないため、Tab順序、ジャンプ後のフォーカス、戻りパスを個別にテストします。動的コンテンツによってターゲットが作成された後、関係性を再確認します。非対応ブラウザでは通常のリンクを維持し、必要なIntersectionObserverによる拡張のみを追加した上で、キーボード、スクリーンリーダー、横スクロール、reduced-motion設定をエンドツーエンドでテストします。」

ステップごとの詳細な回答

ステップ1:安定したアンカーを作成する

各セクションまたはアイテムに一意で予測可能なIDを生成し、ナビゲーションリンクで実際のフラグメントターゲットを使用します。フィルタリング、ページネーション、サーバーレンダリングによって変更される可能性があるため、配列のインデックスのみに依存しないでください。

ステップ2:スクロールマーカーグループを宣言する

サポートされているブラウザでは、目次またはカルーセルコントロールのコンテナにscroll-target-group: autoを設定します。これにより、フラグメントリンクがスクロールマーカーの関係に参加できるようになりますが、フォーカスやセマンティクスまで自動的に設計されるわけではありません。

ステップ3:カレントスタイルとフォーカススタイルを分離する

スクロール位置を表現するにはcurrent-target状態または同等のものを使用し、キーボードフォーカスを表現するには:focus-visibleを使用します。両方が存在する場合は、コントラスト、理解しやすいラベル、控えめなトランジションを維持します。

ステップ4:動的コンテナおよび複数のコンテナを処理する

セクションが読み込まれた後、カルーセルがループした後、またはネストされたスクロールコンテナが変更された後は、ターゲットの一意性とカレントアイテムの安定性を再確認します。1つのリンクが複数のスクロールコンテナによって解釈されないようにし、必要に応じてグループを分割します。

ステップ5:フォールバックと検証を設計する

プロパティがサポートされていない場合でも、通常のアンカーは引き続きジャンプする必要があります。カレントアイテムの表示のためのエンハンスメントとしてのみIntersectionObserverを追加します。キーボード、スクリーンリーダー、ブラウザの「戻る」、ズーム、横スクロール、prefers-reduced-motionをテストします。

質の高い模範回答

まず記事セクションに安定したIDを生成し、実際の目次リンクを使用して、CSSなしでもジャンプが機能するようにします。対象ブラウザがサポートしている場合は、ナビゲーションコンテナにscroll-target-group: autoを設定し、現在のターゲットを強調表示しつつ、:focus-visibleでキーボードフォーカスを可視状態に保ちます。スクロールマーカーはコンテンツ内にフォーカスを移動させないため、意図的なリンクのアクティブ化後のフォーカス動作と戻りパスを検証します。無限読み込みやカルーセルの場合、ターゲットが追加されるたびにIDの一意性とカレントアイテムの安定性を確認します。非対応ブラウザではステータス用のオブザーバーエンハンスメントを備えたアンカーを保持し、デスクトップ、モバイル、スクリーンリーダー、reduced-motion設定でのタスクテストで仕上げます。

よくある間違い

  • 間違い: 実際のアンカーリンクなしでCSSの状態のみを提供する。 → 失敗の理由: 非対応ブラウザや支援技術でナビゲーションが失われます。 → 修正方法: 独立して機能するセマンティックリンクを構築します。
  • 間違い: 表示されているアイテムをキーボードフォーカスとして扱う。 → 失敗の理由: ユーザーはコンテンツをスクロールせずにナビゲーションにフォーカスできるため、状態が競合します。 → 修正方法: カレント状態と:focus-visibleを別々に設計します。
  • 間違い: 配列インデックスからターゲットIDを生成する。 → 失敗の理由: フィルタリングやループ読み込みにより、重複やずれが発生します。 → 修正方法: 安定したビジネス識別子を使用し、更新後に一意性を確認します。
  • 間違い: 実験的プロパティを必須要件としてリリースする。 → 失敗の理由: ブラウザのサポート状況やネストされたスクロールの挙動が異なります。 → 修正方法: アンカーを維持し、機能に応じてエンハンスし、タスクの完了状況を監視します。

フォローアップ質問と回答

フォローアップ1:なぜ単にIntersectionObserverを使用しないのですか?

Observerは既存ブラウザのサポートや複雑なビジネストリガーに役立ちますが、scroll-target-groupはこの状態管理コードを削減できます。これらは階層化が可能です。まずリンクとフォーカスを保護し、その上で保守コストを比較します。

フォローアップ2:横スクロールカルーセルと縦スクロール目次で1つのグループを共有できますか?

通常はできません。スクロール軸、ターゲットの可視性、キーボードモデルが異なるため、カレントアイテムの意味が曖昧になります。スクロールコンテナごとにグループを分割し、個別にラベルを付けます。

フォローアップ3:現在のセクションが変化したときにフォーカスを自動的に移動すべきですか?

受動的なスクロールでフォーカスを移動しないでください。キーボードユーザーの操作を妨げるためです。コンポーネントの仕様に従い、意図的なナビゲーション操作の後でのみフォーカスを移動し、スクリーンリーダーに明確な結果を提供してください。

フォローアップ4:視覚効果の抑制(reduced motion)にはどのように対応しますか?

スムーズスクロールやマーカーのトランジションを減らすか削除しつつ、明確なカレント状態とフォーカスインジケーターを維持します。アニメーションがなくてもナビゲーションがわかりやすい状態を保つ必要があります。

公開情報ソース

関連する質問