CSS 容器查詢技術日漸成熟,許多開發者開始嘗試應用於各種項目,即使只是簡單的實驗。雖然瀏覽器支持度並非完全普及,但在某些項目中已足夠實用,但可能還不足以完全取代舊項目中的媒體查詢。
容器查詢確實非常方便!事實上,我已經遇到過幾次情況,非常希望用到它,但卻受限於瀏覽器兼容性。如果當時可以使用容器查詢,效果將會更好。
以下所有演示在撰寫本文時,最好在 Chrome 或 Safari 中查看。 Firefox 計劃在 109 版本中提供支持。
這個案例大家應該都比較熟悉,對吧?這是一個非常常見的模式,我們幾乎都會遇到。但事實是,如果可以使用容器查詢而不是標準媒體查詢,將會節省大量時間,並獲得更好的結果。
假設您需要構建一個卡片網格,要求每個卡片保持 1:1 的縱橫比:
這比看起來要難!問題在於,根據視口寬度調整組件內容大小,會讓您受制於組件對視口的響應方式,以及任何其他祖先容器對視口的響應方式。例如,如果您希望當卡片達到特定內聯大小時,卡片標題的字體大小減小,則沒有可靠的方法可以做到這一點。
您可以使用 vw 單位設置字體大小,但是組件仍然與瀏覽器的視口寬度綁定。當卡片網格在其他可能沒有相同斷點的上下文中使用時,這可能會導致問題。
在我的實際項目中,我採用了 JavaScript 方法:
看起來工作量很大,對吧?但這是一個穩定的解決方案,可以在不同屏幕尺寸和不同上下文中實現所需的縮放。
容器查詢將會更好,因為它提供了容器查詢單位,例如 cqw 單位。您可能已經了解,1cqw 等於容器寬度的 1%。我們還有 cqi 單位,它是容器內聯寬度的度量,cqb 用於容器塊寬度。因此,如果我們有一個 500px 寬的卡片容器,則 50cqw 的值計算為 250px。
如果在我的卡片網格中可以使用容器查詢,我可以將 .card
組件設置為容器:
<code>.card { container: card / size; }</code>
然後,我可以使用 cqw 單位設置一個具有填充的內部包裝器,該包裝器按 .card
寬度的 10% 縮放:
<code>.card__inner { padding: 10cqw; } </code>
這是一種不錯的方法,可以一致地縮放卡片邊緣與其內容之間的間距,無論卡片在任何給定視口寬度下在何處使用。無需媒體查詢!
另一個想法?使用 cqw 單位作為內部內容的字體大小,然後使用 em 單位應用填充:
<code>.card { container: card / size; }</code>
5cqw 是一個任意值——我只是選擇了一個值。該填充仍然等於 10cqw,因為 em 單位相對於 .card__inner
字體大小!
您注意到了嗎? 2em 相對於在同一容器上設置的 5cqw 字體大小!容器的工作方式與我們習慣的不同,因為 em 單位相對於同一元素的字體大小值。但我很快注意到,容器查詢單位與最近的父級(也是容器)相關。
例如,在這個例子中,5cqw 不會根據 .card
元素的寬度縮放:
<code>.card__inner { padding: 10cqw; } </code>
相反,它會縮放至定義為容器的最近父級。這就是為什麼我設置了一個 .card__inner
包裝器。
在另一個項目中,我還需要另一個卡片組件。這次,我需要卡片在屏幕變小時從橫向佈局過渡到縱向佈局……然後再次回到橫向佈局,再回到縱向佈局。
我完成了這項艱鉅的工作,使該組件在兩個特定的視口範圍內變為縱向(向新的媒體查詢範圍語法致敬!),但問題是它隨後被鎖定在對其、其父級以及可能響應視口寬度的任何其他內容設置的媒體查詢上。我們需要一種在任何情況下都能工作的東西,而不用擔心內容將在哪里中斷!
由於使用了 @container
規則,容器查詢可以輕鬆解決這個問題:
<code>.card__inner { font-size: 5cqw; padding: 2em; } </code>
一個查詢,無限流暢:
但是等等!您可能需要注意一些問題。具體來說,在基於 prop 的設計系統中使用這樣的容器查詢可能很困難。例如,此 .info-card
組件可能包含依賴於 prop 來更改其外觀的子組件。
為什麼這很重要?卡片的縱向佈局可能需要備用樣式,但您無法使用 CSS 更改 JavaScript prop。因此,您可能會重複所需的樣式。我在另一篇文章中實際討論了這一點以及如何解決這個問題。如果您需要將容器查詢用於大量樣式,那麼您可能需要圍繞它們構建整個設計系統,而不是試圖將它們塞入一個依賴媒體查詢的現有設計系統中。
這是我最近使用過的另一個非常常見的模式,如果使用容器查詢,將會得到更完善的產品。假設您有一個與標題鎖定的圖標:
<code>.card { container: card / size; container-name: card; font-size: 5cqw; }</code>
即使沒有媒體查詢,也很容易根據標題的大小縮放圖標。但是,問題是 SVG 的 stroke-width
在較小尺寸下可能會太細而難以注意到,而在較大尺寸下可能會過於粗而過於顯眼。
我不得不為每個圖標實例創建和應用類來確定其大小和描邊寬度。如果圖標位於使用固定字體大小的標題旁邊,這還可以,但是當使用不斷變化的流體類型時,效果就不那麼好了。
標題的字體大小可能基於視口寬度,因此 SVG 圖標需要相應地調整其描邊在任何大小下都能正常工作。您可以通過使用 em 單位設置描邊寬度使其相對於標題的字體大小。但是,如果您需要堅持使用一組特定的描邊大小,則此方法無效,因為它會線性縮放——如果沒有在視口寬度上使用媒體查詢,則無法將其調整到特定描邊寬度值,而不會訴諸於視口寬度上的媒體查詢。
但是,如果我有機會使用容器查詢,我會這樣做:
<code>.card { container: card / size; }</code>
比較這些實現,看看容器查詢版本如何根據容器的寬度將 SVG 的描邊捕捉到我想要的特定寬度。
好的,我實際上並沒有在實際項目中遇到這種情況。但是,當我仔細研究容器查詢的信息時,我注意到我們可以查詢與容器大小或物理尺寸相關的容器的其他內容。
我在這篇文章中一直在使用的示例大多查詢寬度、最大寬度和最小寬度、高度、塊大小和內聯大小。
<code>.card__inner { padding: 10cqw; } </code>
但是 MDN 概述了我們可以查詢的另外兩件事。一個是方向,這非常有意義,因為我們一直在媒體查詢中使用它。容器查詢也是如此:
<code>.card__inner { font-size: 5cqw; padding: 2em; } </code>
另一個是縱橫比,信不信由你:
<code>.card { container: card / size; container-name: card; font-size: 5cqw; }</code>
這是一個可編輯的演示,可以用來試驗這兩個例子:
我還沒有真正找到這兩個的良好用例。如果您有任何想法或覺得它可以幫助您完成項目,請在評論中告訴我!
以上是幾次容器尺寸查詢會幫助我的詳細內容。更多資訊請關注PHP中文網其他相關文章!