CSS Container Query 搭配Grid打造原始碼好維護的靈活排版

以往我們要依據寬度為容器做改變時,我們通常只能用css media query。但media query中帶入的min-width或max-width寬度條件只限用於整個視窗,因此media query常常不能直覺地在Layout需求上實作。

比如說,有一個component,會被應用在主要內容區以及比較窄的sidebar時,我們通常也只能給他一個modifier class name來讓他在sidebar中不會破版。

另外,當父層子層都需要使用media query時,子層不但要處理視窗最寬到最窄的UI編排以外,其中還會經歷父層的變化,導致所需要解的細節問題也就更多。

Container Query 就是用來解決這個長久以來的問題的,算是大家引頸期盼的新功能吧!

目前Safari 16已支援,Chrome也快要支援了,Chrome 105版可以透過此連結開啟功能 chrome://flags/#enable-container-queries

caniuse上顯示個瀏覽器目前的支援度

先來了解一下範例所要顯示的效果。我們想要建立一個圖文列表,會依照視窗寬度決定要顯示成幾欄,圖文區塊則是以欄的寬度來決定左圖右文還是上圖下文。完成後的效果如影片:

紅匡表示的是Body的邊界,.list是一個grid,且會依照視窗的寬度來決定要顯示幾欄,這個就是我們目前熟悉的media query的部分。

裡面的.item在寬度足夠時,左圖右文的排法沒有問題。但若寬度不足且文字過長的時後,一定會破版。因此我設定寬度360px內,讓他變成上圖下文的排法。但因為.list有依據螢幕寬度有不同欄數的設定,因此如果用media query來設定.item的規則時,絕對會設定到死。這時候就是Container Query出場的時候了。

重點來了!使用Container Query時,父層一定要設定container-type,不然瀏覽器不會知道哪個container需要監視寬度,在這個範例我們用container-type: inline-size; 來告訴瀏覽器.item的父層需要監視。

但這時,我們發現,如果設在.list上,監視的是.list整體的寬度,並非欄的寬度。因此我們需要在.item外多包一層.item-wrapper,並且將剛剛設在.list上的container-type改成設在.item-wrapper上,便可以發現成功運作了!

以下是完整的範例程式碼:

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料