代表的な面接トピック

フロントエンド面接:CSS Masonryをどのようにプログレッシブエンハンスメントしますか?

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

質問

高さが可変でキーボード操作順序が考慮されたレスポンシブな画像カードウォールが必要です。CSS Masonryの適用限界を説明し、古いブラウザ向けのプログレッシブエンハンスメント計画を設計してください。

課題の提示とコンテキスト

プロダクト側はメイソンリー形式の画像ウォールを求めています。カードの高さは異なり、デスクトップでは複数列、モバイルでは1列を使用し、キーボードやスクリーンリーダーのユーザー向けにコンテンツが機能しなければなりません。CSS Grid Level 3でメイソンリーレイアウトが定義されつつありますが、構文とブラウザのサポート状況は検証が必要です。ネイティブCSS、カラム、スクリプトのアプローチを比較し、フォールバックとテスト計画を設計してください。

面接官が見ているポイント

  • 視覚的な配置(パッキング)とDOM、読み上げ、フォーカス順序の分離。
  • ブラウザ名による推測ではなく、機能検出とサポートマトリクスを活用しているか。
  • 画像サイズ、CLS、レスポンシブな列数、仮想化、リフローコストへの対処。
  • no-script、キーボード、スクリーンリーダー、ズーム、印刷の受け入れ基準を含めているか。

最初に確認すべき質問

  1. カードは公開時間や優先度に従う必要がありますか、それとも視覚的な列の順序が変わってもよいですか?
  2. メイソンリーは装飾的なものですか、それともユーザーが順番通りにコンテンツを読み、操作する必要がありますか?
  3. どのようなブラウザ、no-script、SEOの制約が適用されますか?
  4. リストは仮想化、ページネーション、または遅延読み込みを必要とするほど大規模ですか?
  5. ドラッグ&ドロップ、動的な挿入、動的な高さ、印刷への対応は必要ですか?

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

セマンティックなDOM順序を固定したまま、視覚的なエンハンスメントのためだけにCSSを使用します。@supportsと実際のブラウザマトリクスを使用して、サポートされている環境ではメイソンリーを選択し、それ以外では通常のGridまたはカラムにフォールバックして余白の違いを許容します。レイアウトシフトを低減するために画像サイズを確保し、JavaScriptをアクセシビリティの唯一の手段には決してしません。コンテンツの順序が一貫していることを確認するため、キーボード、スクリーンリーダー、ズーム、印刷、スクリプト無効時、長いリストのテストを行います。

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

ステップ 1: メイソンリーのトレードオフを定義する

メイソンリーは、一方の軸に沿ってアイテムをグリッドトラック内に詰め込みながら、もう一方の軸を詰めます。これにより空白スペースが減り、視覚的な密度が高まりますが、読み上げ順序、フォーカスの移動、予測可能なページネーションが自動的に解決されるわけではありません。実装を選択する前に、これらのプロダクト要件を受け入れ基準に変換します。

ステップ 2: セマンティクスとフォーカス順序を維持する

実際のリンク、ボタン、見出しをビジネスロジックの順序でレンダリングします。スクリプトでノードを移動したり、正のtabindexで視覚的な順序を修正したりしないでください。視覚的な列がDOMの順序と異なる場合は、それを明示的に許容するか、行ごとの読み上げ順序を維持するために通常のGridを使用します。

ステップ 3: 機能検出とフォールバック

実験的な構文は@supportsの背後に配置し、ターゲットマトリクスでテストします。仕様でサポートされているメイソンリー構文が利用可能な場合はそれを使用し、そうでない場合はdisplay: grid、固定トラック、またはカラムにフォールバックします。フォールバックでも同じDOM、コンテンツ、インタラクションを維持し、余白と配置密度のみが異なるようにします。

ステップ 4: 画像と動的な高さを処理する

サーバーから画像サイズまたはaspect-ratioを出力し、遅延読み込みおよび適切なobject-fitと組み合わせてCLSを削減します。画像の読み込み、フォントの切り替え、コンテンツの更新はリフローを引き起こすため、長いリストはページネーションまたは仮想化を行います。スクリプトによる測定をスロットルし、同期レイアウトを強制するレイアウトの読み取りと書き込みの混在を避けます。

ステップ 5: パフォーマンスと保守性を評価する

CSS、カラム、スクリプトについて、ファーストペイント、スクロールフレームレート、レイアウト時間、メモリ、長いリストへの挿入を個別に測定します。視覚的な差異を最小限に抑えるよう文書化し、ブレークポイントごとにルールを重複させることを避けます。ドラッグ&ドロップ、複雑な列間アニメーション、または明示的なレガシー要件で本当に必要な場合にのみスクリプトを有効にします。

ステップ 6: アクセシビリティと非視覚的な利用を網羅する

すべてのアイテムをTabキーで移動し、フォーカスが不自然に飛ばないことを確認します。スクリーンリーダーを使用して、見出し、リンク、代替テキストがDOMの順序に従っていることを確認します。200%のズーム、ハイコントラスト、視覚効果の抑制(reduced motion)、印刷、スクリプト無効状態をテストします。メイソンリーがコンテンツを取得する唯一の手段であってはなりません。

ステップ 7: リリースと監視

仕様のバージョン、ブラウザマトリクス、フォールバックポリシーを記録します。ブラウザごとにCLS、LCP、スクリプトエラー、オーバーフロー、カードのインタラクション完了率を監視します。構文サポートに変更があった場合は、ロールアウトを拡大する前にスクリーンショットとアクセシビリティのテストケースを実験環境で再実行して検証します。

質の高い模範解答

セマンティックなDOM順序を維持し、メイソンリーを視覚的なエンハンスメントとして扱います。仕様の構文には@supportsと実際のブラウザテストを使用し、同一のコンテンツとインタラクションを保ったまま通常のGridまたはカラムにフォールバックします。CLSを削減するために画像サイズまたはaspect-ratioを確保し、長いリストに対しては頻繁な同期測定を避けてページネーションや仮想化を採用します。キーボード、スクリーンリーダー、ズーム、印刷、no-scriptのテストにより、DOM順序でコンテンツが取得できる必要があります。ブラウザごとにCLS、レイアウトエラー、インタラクション完了率を監視し、仕様更新時はリプレイとアクセシビリティの結果に基づいてロールアウトを制御します。

よくある間違い

  • DOM、フォーカス、スクリーンリーダーの順序を無視して視覚的な密度ばかりを最適化する。
  • @supportsやテストを行わずに、すべてのモダンブラウザが同じメイソンリー構文をサポートしていると思い込む。
  • 順序を修正するためにスクリプトでノードを移動したり、正のtabindexを使用したりする。
  • 画像サイズを省略し、読み込み後にCLSやリフローを発生させる。
  • レイアウトやメモリのコストを測定せずに、互換性のためだけに常にスクリプトを動作させる。

追加の質問と回答

追加質問 1: なぜカラムを使用しないのですか?

カラムはメイソンリーのように見せることができますが、コンテンツは列ごとに分割されるため、読み上げやフォーカスの順序がビジネス要件の順序と異なる場合があります。順序が重要な場合は、通常のGridを優先するか、余白を許容します。

追加質問 2: メイソンリーのサポートをどのように検出しますか?

@supportsとターゲットブラウザマトリクスでの自動テストを使用し、パスした正確なプロパティと値を記録します。User-Agentや「モダンブラウザ」という分類からサポートを推測してはいけません。

追加質問 3: カードを動的に挿入する場合はどうしますか?

挿入順序を維持し、画像サイズを確保し、更新をバッチ処理して、アイテムごとの強制レイアウトを避けます。大規模なリストには、ページネーション、仮想化、フォーカスの復元機能が必要です。

追加質問 4: スクリプトによるフォールバックが正当化されるのはどのような場合ですか?

ドラッグ&ドロップ、複雑な列間アニメーション、またはCSSでは満たせない明示的なレガシー要件がある場合です。スクリプトはあくまでエンハンスメントであり、スクリプトが失敗してもセマンティックなコンテンツは維持されなければなりません。

追加質問 5: 視覚的なレイアウトがアクセシビリティを損なっていないことをどのように証明しますか?

DOMの順序に従ってキーボードとスクリーンリーダーですべてのアイテムを操作し、さらに200%ズーム、視覚効果の抑制(reduced motion)、印刷、スクリプト無効化をテストします。その結果をリリースの判定基準とします。

公開情報ソース

関連する質問