Chrome 正在試驗 css @container 查詢器功能,這是由 Oddbird 的 Miriam Suzanne 和一群網絡平臺開發者支持的 CSS 工作組 Containment Level 3 規范。@container 查詢器使我們能夠根據父容器的大小來設置元素的樣式。
你可以把這些想象成一個媒體查詢(@media),但不是依靠 viewport 來調整樣式,而是你的目標元素的父容器會調整這些樣式。
容器查詢將是自 CSS3 以來 Web 樣式的最大變化,將會改變我們對“響應式設計”含義的看法。
viewport 和用戶代理不再是我們創建響應式布局和 UI 樣式的唯一目標。通過容器查詢,元素將能夠定位自己的父元素并相應地應用自己的樣式。這意味著存在于側邊欄、主體或頭圖中的相同元素可能會根據其可用大小和動態看起來完全不同。
@container 實例
在本示例中,我在父級中使用了兩張帶有以下標記的卡片:
<div class="card-container">
<div class="card">
<figure> ...</figure>
<div>
<div class="meta">
<h2>...</h2>
<span class="time">...</span>
</div>
<div class="notes">
<p class="desc">...</p>
<div class="links">...</div>
</div>
<button>...</button>
</div>
</div>
</div>
復制代碼
然后,我在將查詢容器樣式的父級(.card-container)上設置 Containment(contain 屬性)。我還在 .card-container 的父級上設置了一個相對網格布局,因此它的 inline-size 將根據該網格而改變。這就是我使用 @container 查詢的內容:
.card-container {
contain: layout inline-size;
width: 100%;
}
復制代碼
現在,我可以查詢容器樣式來調整樣式!這與使用基于寬度的媒體查詢設置樣式的方式非常相似,當元素小于指定尺寸時使用 max-width 設置樣式,當元素大于指定尺寸時使用 min-width。
/* 當父容器寬度小于 850px,
不再顯示 .links
并且減小 .time 字體尺寸 */
@container (max-width: 850px) {
.links {
display: none;
}
.time {
font-size: 1.25rem;
}
/* ... */
}
/* 當父容器寬度小于 650px 時,
減小 .card 元素之間的網格間距到 1rem */
@container (max-width: 650px) {
.card {
gap: 1rem;
}
/* ... */
}
復制代碼
容器查詢 + 媒體查詢
容器查詢的最佳功能之一是能夠將 微觀上的布局 與 宏觀上的布局 分開。我們可以使用容器查詢設置單個元素的樣式,創建細微的微觀布局,并使用媒體查詢(宏布局)設置整個頁面布局的樣式。這創造了一個新的控制水平,使界面更具響應性。
這是另一個示例。它展示了使用媒體查詢進行宏觀布局(即日歷從單面板到多面板)和微觀布局(即日期布局/大小和事件邊距/大小移動),以創建一個漂亮的和諧的查詢。
容器查詢 + CSS 網格
我個人最喜歡的查看容器查詢影響的方法之一是查看它們在網格中的工作方式。以下面的植物貿易 UI 為例:
本網站根本沒有使用媒體查詢。相反,我們只使用容器查詢和 CSS 網格來在不同的視圖中顯示購物卡組件。
在產品網格中,布局使用了 grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); 標記創建。這將創建一個布局,告訴卡片占用可用的小數空間,直到它們的大小達到 230px,然后下一格切換到下一行。你可以在 1linelayouts.com 上查看更多網格技巧。
然后,我們有一個容器查詢,當卡片寬度小于 350px 時,它會將卡片樣式設置為采用垂直塊布局,并通過應用 display: flex(默認情況下具有內聯流)轉換為水平內聯布局。
@container (min-width: 350px) {
.product-container {
padding: 0.5rem 0 0;
display: flex;
}
/* ... */
}
復制代碼
這意味著每張卡片擁有自己的響應式樣式。這是我們使用產品網格創建宏觀布局以及使用產品卡片創建微觀布局的另一個示例,酷斃了!
用法
為了使用@container,首先需要創建一個具有 Containment 的父元素。為此,我們需要在父級上設置 contain: layout inline-size。因為我們目前只能將容器查詢應用于內聯軸,所以我們只可以使用 inline-size。這也可以防止我們的布局在塊方向上中斷。
設置 contain: layout inline-size 會創建一個新的 Containment 塊 和新的塊格式上下文,讓瀏覽器將其與布局的其余部分分開,現在我們就可以使用容器查詢了!
限制
目前,您不能使用基于高度的容器查詢,只能使用塊軸方向上的查詢。為了讓網格子元素與 @container 一起工作,我們需要添加一個容器元素。盡管如此,添加容器仍可讓我們獲得所需的效果。
試試看
您現在可以在 Chromium 中試驗 @container 屬性,方法是導航到:Chrome Canary 中的 chrome://flags 頁面并打開 #
experimental-container-queries 標志。