原文:https://ishadeed.com/article/container-query-units/
作者:Ahmad Shadeed
譯者:Levix
幾天前,我看到 Miriam Suzanne 關於支持 CSS 容器查詢單位的一條推特,這最初是由 Github 上的 Una Kravets 提出的。忍不住嘗試使用了它們,看看我們如何從 CSS 容器查詢中獲得更多發揮的空間。
我將盡力解釋每個單位是如何工作的,以及我們可以在哪些地方使用一個(或多個)單位來加強組件如何對其父級寬度做出適配。如果你還沒聽過 CSS 容器查詢,我寫了一篇介紹了很多例子,以及容器查詢如何影響設計師的工作,我建議你在閱讀本文之前先閱讀這兩篇文章。
溫馨提示:CSS 容器查詢僅支持在具備實驗性標誌的 Chrome Canary 版本瀏覽器中使用。其他版本要使用它,請到 chrome://flags 搜索 “Enable CSS Container Queries” 並啟用該功能。
讓我們深入了解一下。
簡介#
在 CSS 中,我們有很多單位可以用於不同的場景,最常用的是 px
、 rem
和 em
。如果有類似於 CSS 容器查詢工作方式的單位,那麼我覺得應該是視口單位。
CSS 視口單位的工作原理基於適配瀏覽器的視口尺寸(寬度或 / 和高度),這很棒,但我們並不是總想使用與視口尺寸有關的單位,如果我們想針對容器的寬度進行查詢呢?這就是查詢單位的作用。
為了更清楚地說明問題,我想強調視口單位和查詢單位之間的區別。請看下圖:
左邊區域, font-size
相對於視口寬度由 rem
和 vw
控制,在某些情況下,這種方式會起作用,但由於它是相對於視口尺寸可能會引發意想不到的問題。
在處理諸如 font-size
、 padding
、margin
等問題時,查詢單位可以節省我們的時間和精力,我們可以使用查詢單位來作為手動增加字體大小的替代方式。
參考下面的例子。
我們有一個開始狀態是堆疊式的卡片式組件,隨著容器變大,慢慢變成主橫幅的樣式,對於這樣的組件,我們可能需要修改以下內容:
- 縮略圖大小
- 字體大小
- 元素之間的間距
如果沒有 CSS 查詢單位,我們需要手動更改上面的內容。
.card {
/* The stacked, base style */
}
.card__title {
font-size: 1rem;
}
/* The horizontal style, v1 */
@container (min-width: 400px) {
.card__title {
font-size: 1.15rem;
}
}
/* The horizontal style, v2 */
@container (min-width: 600px) {
.card__title {
font-size: 1.25rem;
}
}
/* The hero style */
@container (min-width: 800px) {
.card__title {
font-size: 2rem;
}
}
注意到 .card__title
的字體大小是如何隨著不同的容器查詢而改變的,我們可以通過使用查詢單位和 CSS clamp()
函數來加強這一點並避免重複設置 font-size
。
.card__title {
font-size: clamp(1rem, 3qw, 2rem);
}
這樣,我們只需要定義一次 font-size
,如果我們想要直觀地比較一下,它是下面這樣的:
如果你熟悉 CSS 視口單位,這對你來說並不陌生,這就像基於容器而不是瀏覽器的視口進行查詢,挺簡潔的,不是嗎?
查詢單位#
現在我們已經了解了查詢單位應該解決的問題,讓我們根據 CSS 規範繼續掌握這些單位:
- 查詢寬度(qw):容器寬度的 1% 。例如, 5qw 將解析為容器寬度的 5% 。
- 查詢高度(qh):容器高度的 1% 。例如,5qh 將解析為容器高度的 5% 。
- 查詢最小值(qmin):查詢寬度
qw
或查詢高度qh
的較小值。 - 查詢最大值(qmax):
qw
或qh
的較大值。
我們還有另外兩個單位: qi
和 qb
,它們分別表示查詢內聯和查詢塊(尺寸),它們適用於我們有不同寫作模式的情況。
案例與例子#
卡片組件#
除了之前講解過關於卡片的例子,我們還可以在堆疊式卡片使用查詢單位,我們希望字體大小基於容器的寬度而稍大一些。
請注意,字體大小根據容器尺寸而進行細微變大,這對於創建一個無論放在哪裡都能工作的堆疊卡片是很有用的。
根據權重改變 font-size
#
當一個元素比另一個元素更大時,表明它可能更加重要,一個很好的例子就是側邊欄以及主體, <aside>
中標題大小應該小於 <main>
部分的標題。
注意到 <aside>
中的標題是如何比 <main>
中的標題小的,由於有了查詢單位,我們可以很容易地實現這一點。
首先,我們需要將 <aside>
和 <main>
定義為 inline-size 容器。
aside,
main {
container: inline-size;
}
接著,我們對章節標題設置查詢單位,我們還可以對底部邊距使用查詢單位。
.section-title {
font-size: clamp(1.25rem, 3qw, 2rem);
margin-bottom: clamp(0.5rem, 1.5qw, 1rem);
}
個人簡介組件#
簡介可以放在一個較小的容器中(例如:側邊欄),或顯示在移動視口,或像頁面標題這樣的大容器中。
我們可以構建一個可以適應其容器寬度的組件,在本例中,用戶的頭像和字體大小根據其容器的寬度而改變。
.bio {
container: inline-size;
}
.c-avatar {
--size: calc(60px + 10qw);
width: var(--size, 100px);
height: var(--size, 100px);
margin-bottom: clamp(0.5rem, 3qmin, 2rem);
}
帶計數器的標題#
在某些情況下,我們需要在有文章正文標題旁邊顯示一個計數器,這是查詢單位的一個完美用例。
.article-body {
counter-reset: heading;
}
h2 {
container: inline-size;
font-size: clamp(1.25rem, 3qw, 2rem);
margin-bottom: clamp(0.5rem, 1.5qw, 1rem);
}
h2:before {
--size: calc(1.25rem + 3qw);
content: counter(heading);
counter-increment: heading;
width: var(--size);
height: var(--size);
font-size: calc(0.85rem + 1qw);
margin-right: calc(var(--size) / 4);
}
動態間距#
我們已經使用視口單位創建動態間距的 CSS 網格,它是這樣的:
.wrapper {
gap: calc(1rem + 2vw);
}
這很酷,但是在特定包裝器中的組件呢?使用視口單位是行不通的,這就是為什麼這種情況下,使用查詢單位是一個很好的解決方案。
.card {
display: flex;
flex-direction: column;
gap: calc(0.5rem + 1qmin);
}
當組件切換到水平風格時,間距會大一些。
如果我們在沒有定義容器的情況下使用查詢單位會發生什麼?#
根據規範:
如果沒有合適的查詢容器,那麼就使用該軸的小視口尺寸。
瀏覽器會像處理視口單位一樣處理查詢單位,請看下面的例子:
h2 {
font-size: clamp(1.25rem, 3qw, 2rem);
}
如果沒有為 <h2>
定義容器,瀏覽器會認為 3qw
是視口寬度的 3%
,這意味著在沒有定義容器的情況下,使用查詢單位會導致意想不到的結果。
我希望你喜歡這篇文章,感謝你的閱讀!