CSS @container 沒生效?讓外層量尺寸、內層改版面
本文目錄
同一張卡片放進側欄要直排,放進主欄則可以橫排。若把 container-type: inline-size 和 @container 裡要修改的版面都設在卡片本身,瀏覽器會從卡片的祖先找查詢容器。卡片自己的尺寸無法作為這條規則的條件。把容器設在外層插槽,再讓規則改內層卡片即可。
用同一個視窗比對兩張卡片
把以下內容存成 HTML,用支援尺寸容器查詢的瀏覽器開啟。兩張卡片共用同一個樣式,在視窗足以容納 400px 寬插槽時,窄插槽會看到直排,寬插槽則是兩欄。因為插槽各有自己的尺寸,兩個結果可以在同一個 viewport 同時出現。
<!doctype html><html lang="zh-Hant"><meta charset="utf-8"><title>容器查詢測試</title><style> .slot { container: feature-slot / inline-size; max-inline-size: 100%; margin-block: 12px; }
.slot--narrow { inline-size: 240px; } .slot--wide { inline-size: 400px; }
.card { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; padding: 12px; border: 1px solid; }
.card__thumb { min-block-size: 56px; background: #89c5c0; }
@container feature-slot (inline-size >= 320px) { .card { grid-template-columns: 96px minmax(0, 1fr); } }</style><div class="slot slot--narrow"> <article class="card"> <div class="card__thumb" aria-hidden="true"></div> <div>窄插槽:縮圖與文字直排</div> </article></div><div class="slot slot--wide"> <article class="card"> <div class="card__thumb" aria-hidden="true"></div> <div>寬插槽:縮圖與文字橫排</div> </article></div></html>在開發者工具選寬插槽的 .card,查看 Computed 裡的 grid-template-columns,第一欄應是 96px;窄插槽則只有一欄。接著把寬插槽改成 319px,同一張卡片應回到直排。若把 container: feature-slot / inline-size 從 .slot 移到 .card,兩張卡片都會走直排的基礎規則。
套進現有版面時,先找已經有寬度的外層
CSS Conditional Rules Level 5定義的是先從目標元素往上找最接近、支援查詢軸且名稱相符的祖先,再對它判斷尺寸。命名 feature-slot 可以略過途中其他名稱的容器;如果最近的合格容器只有 240px,瀏覽器不會因為條件為假,再往上改用更寬的容器。外層已有 grid 欄位或 flex 插槽時,可以直接把它設為查詢容器,省去一層 DOM。
尺寸查詢使用容器的內容盒,inline-size 在水平書寫模式下是寬度。若外框看起來超過斷點,但容器有 padding 或 border,請看開發者工具顯示的內容盒。另留意 container-type: inline-size 會讓容器的 inline 尺寸不依賴子元素的固有尺寸;原先靠內容撐寬的外層,應改由既有欄位或明確尺寸提供空間。若切成兩欄後是長文字撐爆內層,則是另一個問題,可接著檢查 Flexbox 省略號與最小寬度。
參考資料: