題幹與適用場景
一個卡片元件會同時出現在主內容區、側欄與網格中。請解釋 CSS 容器查詢與媒體查詢的差異,寫出依卡片容器寬度切換版面的 CSS,並說明容器建立、查詢作用域、回退與測試方案。
媒體查詢根據視口或裝置特徵判斷;容器查詢根據祖先查詢容器的尺寸、樣式或捲動狀態判斷。GreatFrontEnd 的 CSS 面試資料直接把容器查詢列為面試題,Hack Frontend 的 HTML/CSS 題單也涵蓋此主題;MDN 文件說明了 container-type、@container 與容器查詢單位的規範行為。本文不綁定特定公司。
面試官考察點
面試官會看候選人能否先區分響應對象,再寫出完整上下文。高品質回答應說明 container-type: inline-size 建立尺寸查詢上下文,查詢規則作用於後代而非容器本身,預設匹配最近的合格祖先,並解釋為何同一視口下不同卡片寬度需要容器查詢。
還要檢查是否理解尺寸包含的副作用、命名容器的邊界、舊瀏覽器回退與測試方法。只把 @media 改成 @container,卻沒有建立容器或處理巢狀關係,程式碼無法按預期工作。
回答前需要澄清的問題
- 響應什麼尺寸? 本題響應卡片分配到的內聯尺寸,不響應整個視口。
- 是否需要樣式或捲動狀態查詢? 本題只需要尺寸查詢;樣式查詢與捲動狀態查詢屬於可選擴充。
- 相容範圍是什麼? 先確認目標瀏覽器;不支援容器查詢時保留可用的基礎版面與媒體查詢回退。
- 元件邊界是否巢狀? 若有巢狀卡片,使用
container-name明確指定應讀取哪一層。
30 秒回答框架
「媒體查詢觀察視口,適合頁面級斷點;容器查詢觀察元件祖先容器,適合同一元件在不同版位重用。先在卡片外層設定 container-type: inline-size,再用 @container 依容器內聯尺寸切換版面。查詢只影響後代,預設使用最近的合格容器;複雜巢狀關係用 container-name。我會提供基礎樣式與 @supports 回退,並在固定視口下調整父容器寬度,測試主區、側欄、網格與不支援特性的瀏覽器。」
分步驟深入解答
第一步:先比較響應對象與作用域
| 維度 | 媒體查詢 | 容器查詢 |
|---|---|---|
| 響應對象 | 視口、裝置或使用者偏好 | 祖先查詢容器的尺寸、樣式或捲動狀態 |
| 典型範圍 | 頁面級版面 | 可重用元件內部版面 |
| 建立方式 | @media 直接讀取媒體特徵 | 祖先設定 container-type,後代使用 @container |
| 元件行為 | 同一視口通常共享斷點 | 每個實例可依實際分配寬度響應 |
媒體查詢適合導覽、整頁欄列與列印等頁面級決策。容器查詢解決的是元件不知道會被放入多寬的版位:主欄與側欄可以在同一視口下採用不同版面。
第二步:建立尺寸查詢上下文
.card-list {
container-type: inline-size;
container-name: card-list;
}
.card {
display: grid;
gap: 0.75rem;
}
@container card-list (inline-size > 40rem) {
.card {
grid-template-columns: 8rem 1fr;
align-items: center;
}
}inline-size 建立依內聯軸尺寸查詢的容器,適合同時考慮不同書寫模式的元件。size 會建立更強的雙軸尺寸包含,只有在確實需要塊軸查詢時才使用。normal 不建立尺寸查詢上下文。查詢條件寫在 @container 中,規則匹配容器的後代。
第三步:理解最近容器、命名與查詢單位
未指定名稱時,瀏覽器尋找最近的合格祖先;巢狀元件可能因此讀到錯誤邊界。命名容器可以把意圖寫清楚:@container card-list (...) 只匹配名為 card-list 的容器。容器查詢長度單位如 cqw、cqi 可依查詢容器寬度或內聯尺寸縮放,但仍應配合合理的最小值與最大值,避免小容器產生不可讀文字。
查詢規則不能讓容器本身依自己的查詢結果改變尺寸,否則會形成回饋循環;規範透過包含與作用域限制避免此循環。尺寸包含也可能改變自動尺寸計算,因此要檢查空內容、圖片尚未載入與高度依賴內容的情況。
第四步:設計回退與漸進增強
.card {
display: block;
}
@supports (container-type: inline-size) {
.card-list {
container-type: inline-size;
}
@container (inline-size > 40rem) {
.card {
display: grid;
grid-template-columns: 8rem 1fr;
}
}
}基礎版面應在沒有容器查詢時仍然可讀。媒體查詢可以作為頁面級兜底,但不能假設視口斷點能準確代表側欄或網格單元寬度。若目標瀏覽器不支援 @supports 檢測的能力,就停留在基礎樣式,不影響核心內容與操作。
第五步:用場景與邊界驗證
固定瀏覽器視口,分別把同一元件放入主欄、側欄與兩欄網格,再只調整父容器寬度,觀察卡片是否按容器而非視口切換。測試巢狀命名容器、不同書寫模式、圖片載入前後、極窄容器、動態版位與不支援容器查詢的瀏覽器。還要確認元件沒有依賴某個頁面 DOM 層級,否則重用時會靜默匹配到錯誤容器。
可接受的實作邊界
回答不必涵蓋所有查詢類型,但必須準確區分視口與祖先容器,並讓範例具備可運作的容器上下文。若選擇 size、樣式查詢或捲動狀態查詢,應說明額外的包含影響、瀏覽器目標與測試邊界;若不確定相容範圍,應明確把基礎版面作為安全預設值。
常見錯誤與反例
- 忘記設定
container-type:只有@container沒有查詢上下文,規則不會按尺寸生效。 - 把容器寫成自身查詢目標:查詢規則只能穩定地影響後代,不能讓容器依自己結果循環改變尺寸。
- 把
size當作預設值:雙軸包含會影響自動尺寸,元件只關心橫向時優先inline-size。 - 只在大螢幕測試:同一視口下側欄與主欄寬度不同,必須固定視口並調整父容器驗證。
- 沒有基礎回退:舊瀏覽器中卡片可能失去版面,基礎樣式應先保證內容可用。
追問及應對
什麼時候仍然使用媒體查詢?
導覽、整頁欄列、列印與使用者偏好等決策依賴視口或媒體特徵時,媒體查詢更直接。元件內部斷點依賴父容器時,再使用容器查詢。
inline-size 與 size 如何選擇?
只按橫向可用空間響應時選擇 inline-size;需要同時按塊軸與內聯軸查詢時才考慮 size,並驗證自動尺寸、空內容與圖片載入後的結果。
如何處理不支援容器查詢的瀏覽器?
提供基礎單欄或流式版面,用 @supports (container-type: inline-size) 漸進增強;媒體查詢可以補充頁面級體驗,但不能取代所有容器級斷點。