CSS容器查詢獲得主流瀏覽器支持,是什么?怎么用?
近期,主流瀏覽器終于都支持了 CSS 容器查詢功能:
在引入響應式設計之前,許多公司通過提供不同的站點來處理基于屏幕尺寸更改布局的問題。2010 年,Ethan Marcotte 引入了響應式設計的概念。響應式網(wǎng)頁設計的理念是設計和開發(fā)應根據(jù)屏幕尺寸、設備和方向響應用戶的行為和環(huán)境。這個想法實現(xiàn)的核心就是 CSS 媒體查詢,它允許根據(jù)視口的大小設置各種布局規(guī)則。
如今,開發(fā)人員通常使用基于組件的 JavaScript 框架(如 React、Vue 等)以及 CSS 框架(如 Tailwind CSS、Material UI 和 Bootstrap)來制作響應式和可重用的布局和應用。一種新的響應式設計方法出現(xiàn)了——容器查詢,容器查詢可以根據(jù)組件的大小或樣式而不是設備的視口直接查詢組件。
媒體查詢的問題?
在介紹容器查詢之前,先來看看媒體查詢的概念。通常網(wǎng)頁由不同的組件組成,我們可以通過使用 CSS 媒體查詢使它們具有響應性。但是它是有局限性的。例如,可以使用媒體查詢在移動設備和桌面設備上顯示組件的最小版本。
通常,響應式網(wǎng)頁設計與視口或屏幕尺寸無關,而是于容器的大小有關。來看下面的例子:
這里是一個非常經(jīng)典的帶有卡片組件布局,這里有兩種顯示形式:左側(cè)的堆疊式和右側(cè)的平鋪式。
這在CSS 中有多種實現(xiàn)方法,最常見的方法如下所示。我們需要創(chuàng)建一個基礎組件,然后對其進行媒體查詢:
這里創(chuàng)建了 .c-article--horizontal? 類來處理組件的平鋪部分,如果視口寬度大于 46rem,則組件應切換到平鋪模式。這確實可以實現(xiàn)預期的效果,但是有局限,我們希望組件根據(jù)其父級寬度進行變化,而不是瀏覽器的視口或屏幕尺寸。
可以用 CSS 容器查詢來實現(xiàn)這個布局。我們需要當右側(cè)區(qū)域的父級大于 400px 時切換到平鋪模式:
使用容器查詢,就可以在將組件放入窄的父組件中,它會變成堆疊版本,將組件放入寬的父組件中,它會變成平鋪版本,所有這些都與視口寬度無關。
上面的代碼只是簡單的實現(xiàn),下面就來看看 CSS 容器查詢特性是如何使用的!
什么是容器查詢?
容器是包含另一個元素的元素。因此,簡單來說,CSS 容器查詢就是指定元素相對于其父容器或元素的更改,而不是整個視口。
因此,仍然可以使用響應式網(wǎng)格來進行整體頁面布局,但該網(wǎng)格中的組件可以通過查詢其容器來定義自己的行為變化。然后,它可以根據(jù)它是在窄容器還是寬容器中顯示來調(diào)整其樣式。
容器查詢能夠以非常精確和可預測的方式定義組件的全部樣式,例如:增加或減少padding、更改字體大小、添加或刪除背景圖片,或者更改子元素的 display 屬性和方向。
如何使用容器查詢?
容器查詢中的“容器”就是被查詢的元素,但是容器查詢中規(guī)則僅影響后代元素。容器查詢將允許定義這些元素如何在容器大小之間變化的規(guī)則。
容器查詢語法
要想設置容器查詢,需要給被查詢的元素設置 container-type 屬性來指定容器的類型。語法如下:
container-type 屬性有以下屬性值:
- size:創(chuàng)建一個查詢?nèi)萜?,支持?nèi)聯(lián)軸和塊軸維度上進行查詢。
- inline-size:創(chuàng)建一個查詢?nèi)萜?,支持在?nèi)聯(lián)軸(文本流方向)維度上進行查詢,這是最常用的選項。
- block-size:創(chuàng)建一個查詢?nèi)萜?,支持在塊軸維度上維度查詢。
- style:允許通過定義查詢?nèi)萜鬟M行樣式查詢。
- state:允許通過定義查詢?nèi)萜鬟M行狀態(tài)查詢。
例如:
我們可以使用 container-name 屬性為容器指定一個名稱,以區(qū)分具有唯一名稱的容器。
現(xiàn)在,我們就可以使用 card 為對應容器定義容器查詢:
這樣,定義的容器查詢樣式就不會干擾到其他容器,只會對指定的容器生效。
我們可以使用 container? 來簡寫 container-type? 和 container-name 屬性,格式如下:
下面來看一個例子:
這里我們給 main? 標簽定義了一個 container? 類,它將作為容器查詢中的容器。接下來,可以設置一個容器查詢來更改文章及其任何后代,這些樣式將基于 main 的寬度發(fā)生改變。使用容器查詢會隨著容器的增長而改變樣式。
這里的代碼很簡單,當容器 container? 的寬度達到 60ch 時,就增大 padding? 和 font-size 的值。
- min-width?:當容器的大于或等于指定的寬度時,min-width 定義的樣式會生效;
- max-width?:當容器的小于或等于指定的寬度時,max-width 定義的樣式會生效;
- @container:檢測元素的父元素何時更改寬度,并指定每次寬度更改時要在子元素中進行哪些更改。
容器查詢長度單位
除此之外,容器查詢還引入了幾個專用的長度單位,當使用容器查詢將樣式應用于容器時,可以使用容器查詢長度單位。這些單位指定相對于查詢?nèi)萜鞒叽绲拈L度。使用相對于其容器的長度單位的組件可以更靈活地用于不同的容器,而無需重新計算具體的長度值。
容器查詢長度單位包含:
- cqw:查詢?nèi)萜鲗挾鹊?1%
- cqh:查詢?nèi)萜鞲叨鹊?1%
- cqi:查詢?nèi)萜鲀?nèi)聯(lián)大小的 1%
- cqb:查詢?nèi)萜鲏K大小的 1%
- cqmin:cqi? 或 cqb 中較小的值
- cqmax:cqi? 或 cqb 中較大的值
下面來看一個例子,根據(jù)容器的大小來設置二級標題的字體大?。?/p>
容器元素選擇器規(guī)則
上面我們說過,容器本身是不能在容器查詢中設置樣式的(除非它是嵌套容器并響應其祖先容器的查詢)。但是,容器可以用作其子項的 CSS 選擇器的一部分。
這有什么作用嗎?這樣的話,就可以保留對可能需要源自容器的 CSS 偽類和選擇器的訪問,例如 :nth-child。
舉個例子
卡片布局
下面來看一個卡片布局的例子:
當有四個元素時,是這樣的:
卡片的數(shù)量減少時,由于我們使用了 auto-fit 屬性,卡片的寬度就會變寬。
這看起來太寬了,影響了視覺效果。如果每個卡片的布局能根據(jù)父元素的寬度來設置就太好了,這時就可以使用容器查詢:
效果如下:
這樣就得到了一個根據(jù)父級寬度進行樣式響應的卡片組件。
表單布局
下面再來看一個表單的例子,當表單所在容器寬度不同時,分別顯示為水平或堆疊模式。
可以用容器查詢輕松實現(xiàn)該布局:
完成了這個樣式,可以給父元素添加一個resize屬性,使其大小可變,以測試容器查詢是否生效:
使用容器查詢完美實現(xiàn)了預期效果!
調(diào)試容器查詢
目前 Chrome DevTools 中已經(jīng)支持檢查和調(diào)試容器查詢。在 Elements 中,容器元素后面會顯示 container 標志:
當容器滿足查詢條件時,可以檢查@container應用于后代的規(guī)則:
當鼠標懸浮在父元素(div.form-item)上時,就會顯示當前父元素的寬度:
參考:
[1] https://ishadeed.com/article/say-hello-to-css-container-queries/
[2] https://developer.chrome.com/en/blog/devtools-tips-9/
[3] https://web.dev/cq-stable/?