前端面試:如何為 CSS Masonry 版面設計漸進增強?
題幹與適用場景
產品希望做瀑布流圖片牆:卡片高度不同,桌面多欄、行動端單欄,內容需要鍵盤和螢幕閱讀器可用。CSS Grid Level 3 正在定義 Masonry 版面,但瀏覽器支援與語法仍需核對。請比較原生 CSS、欄布局和腳本方案,並給出不支援時的回退與驗證。
面試官考察點
- 是否區分視覺緊湊排列與 DOM、閱讀和焦點順序。
- 能否根據規範狀態和實際支援做 feature detection,而非憑瀏覽器名稱判斷。
- 能否處理圖片尺寸、CLS、響應式欄數、虛擬化和重排成本。
- 是否把無腳本、鍵盤、螢幕閱讀器和列印場景納入驗收。
回答前需要釐清的問題
- 卡片順序必須按發布時間、優先級,還是允許按欄視覺順序變化?
- Masonry 是裝飾性網格,還是使用者需要按順序閱讀和操作的內容?
- 目標瀏覽器、無腳本要求和 SEO 約束是什麼?
- 圖片數量是否達到需要虛擬化、分頁或懶載入的規模?
- 是否必須支援拖曳、插入、動態高度和列印?
30 秒回答框架
我會先固定語意 DOM 順序,再用 CSS 做視覺布局。對支援的瀏覽器透過 @supports 選擇 Masonry;不支援時回退到普通 Grid 或多欄布局,接受間隙差異。圖片預留寬高,避免布局跳動;不把 JavaScript 作為無障礙必要路徑。用鍵盤、讀屏、縮放、列印和長清單測試視覺與 DOM 順序是否仍一致。
分步驟深入解答
第一步:定義 Masonry 的取捨
Masonry 目標是讓項目沿一個軸按網格軌道排列、沿另一個軸緊湊堆疊。它解決的是空白減少和視覺密度,不會自動解決內容閱讀順序、焦點移動或可預測分頁。先把產品約束寫成驗收標準,再選實作。
第二步:保持語意與焦點順序
使用真實連結、按鈕和標題,DOM 順序按業務順序輸出。避免透過腳本重排節點或用正數 tabindex 修補視覺順序。若視覺欄順序與 DOM 順序不同,在設計上接受差異,或改用普通 Grid 保證逐行閱讀。
第三步:做能力偵測與回退
把實驗性語法放在 @supports 中,並在目標瀏覽器矩陣實測。支援時使用規範推薦的 Masonry 語法;不支援時回退到 display: grid、固定軌道或欄布局。回退應保持相同 DOM、內容和互動,差異只體現在空白與排列密度。
第四步:處理圖片與動態高度
伺服器輸出圖片寬高或 aspect-ratio,配合懶載入和合適的 object-fit,減少 CLS。圖片載入、字型替換和內容更新會觸發重排,長清單應分頁或虛擬化。腳本測量布局時要節流,並避免讀寫布局交錯導致強制同步布局。
第五步:評估效能與可維護性
對 CSS、欄布局和腳本方案分別測量首屏、滾動幀率、布局耗時、記憶體和長清單插入。保留最小化的視覺差異說明,避免為每個斷點複製規則。腳本方案只有在拖曳、跨欄動畫或舊瀏覽器要求確實需要時才啟用。
第六步:覆蓋無障礙與非視覺場景
用鍵盤逐項訪問,驗證焦點不跳躍;用螢幕閱讀器確認標題、連結和圖片替代文字按 DOM 順序出現。放大到 200%、高對比、減少動效、列印和停用腳本仍應可讀。瀑布流不能成為取得內容的唯一方式。
第七步:發布與監控
記錄規範版本、瀏覽器支援矩陣和回退策略。線上監控 CLS、LCP、腳本錯誤、布局溢出和卡片互動完成率,按瀏覽器分組觀察。瀏覽器語法變化時先在實驗環境回放截圖和無障礙用例,再擴大範圍。
高品質示範回答
我會保留按業務順序的語意 DOM,並把 Masonry 作為視覺增強。用 @supports 和真實瀏覽器矩陣檢測規範語法;不支援時回退到普通 Grid 或欄布局,保持同一內容和互動。圖片輸出尺寸或 aspect-ratio 以降低 CLS,長清單用分頁或虛擬化而非頻繁同步測量。鍵盤、讀屏、放大、列印和停用腳本都必須能按 DOM 順序取得內容。線上按瀏覽器監控 CLS、布局錯誤和互動完成率,規範更新先做回放和無障礙驗收。
常見錯誤
- 只看視覺緊湊度,忽略 DOM、焦點和螢幕閱讀順序。
- 假設所有現代瀏覽器都支援同一 Masonry 語法,不做
@supports和實測。 - 用正數
tabindex或腳本搬運節點修補順序。 - 圖片沒有尺寸,載入後導致大量 CLS 和重排。
- 為了相容性引入常駐腳本,卻沒有測量其布局和記憶體成本。
追問及應對
追問一:為什麼不用多欄布局?
多欄布局能產生瀑布流視覺,但內容按欄分段,閱讀和焦點順序可能與業務順序不同。若順序重要,應優先普通 Grid 或接受空白。
追問二:如何判斷 Masonry 語法可用?
使用 @supports 和目標瀏覽器自動化測試,按規範文件記錄通過的屬性和值。不能只按 User-Agent 或「現代瀏覽器」標籤推斷。
追問三:動態插入卡片怎麼辦?
保持 DOM 插入順序,給圖片預留尺寸,批量更新並避免逐項強制布局。長清單需要分頁、虛擬化和可恢復焦點。
追問四:腳本回退什麼時候合理?
當拖曳、複雜跨欄動畫或明確的舊瀏覽器支援要求無法由 CSS 滿足時。腳本應是增強層,失敗時仍保留語意內容。
追問五:如何證明無障礙沒有被視覺布局破壞?
用鍵盤和螢幕閱讀器按 DOM 順序逐項操作,結合 200% 縮放、減少動效、列印和停用腳本測試,並把結果納入發布門禁。