如何實現更細緻的響應式設計?初探 CSS 的容器查詢(Container Query)

zxlee-avatar-img
發佈於CSS
更新 發佈閱讀 8 分鐘

傳統的響應式設計多半是透過媒體查詢(media query)來達成。在版型設計的情境下,媒體查詢通常是根據視窗(viewport)的寬度進行調整;然而,這樣的設計方式在某些情況下,可能會產生不符合預期的結果。

舉例來說,你可能會希望某一個元件,能夠同時被使用在全寬的主要內容區塊,以及寬度較窄的側欄中。但如果該元件的響應式行為是完全依賴視窗寬度來決定,那麼當畫面處於大螢幕時,元件可能會套用「桌機版」的樣式,卻被放進空間有限的側欄,進而產生跑版或擠壓的問題。

下方是我參考 Web Dev Simplified 教學影片寫的簡易範例,如果你是在螢幕寬度 800px 以上查看的話,應該會看到如下方截圖呈現的版面:

raw-image

而這類「元件本身所在空間,與視窗尺寸脫鉤」的情境,正是容器查詢(container query)所要解決的問題。

什麼是容器查詢(Container Query)?

容器查詢的核心概念在於:元件的樣式不再依據整個視窗大小,而是依據「它所在的容器尺寸」來調整。

換句話說,容器查詢讓元件可以根據「實際可用空間」來決定自己的版型,而不是被迫跟隨全域的 viewport 規則,這使得元件更容易被重複使用於不同版位之中。

如何使用容器查詢?

相較於媒體查詢,容器查詢在使用前需要多一道關鍵步驟:宣告容器。你必須先明確告訴瀏覽器,哪些元素可以作為查詢尺寸的依據。

1. 宣告容器

.wrapper {
container-type: inline-size;
}

我們透過 container-type 來指定一個元素為「可被查詢的容器」。常見的設定值有以下兩種:

  • inline-size:只允許查詢容器的 inline-size(在一般水平書寫模式下,等同於寬度),也是目前最常見、最推薦的用法。
  • size:允許同時查詢容器的 inline-size 與 block-size(寬度與高度)。由於會影響版面計算,且需要計算 block-size 的情境較少,實務上較少使用。

後續範例皆以 inline-size 為主。

2. 查詢容器尺寸

在宣告容器之後,就可以透過 @container 語法,根據該容器的尺寸來調整樣式。

@container (min-width: 375px) {
/* 當容器的 inline-size ≥ 375px 時套用的樣式 */
}

語法上與 @media 非常相似,但需要特別注意的是:

這裡的 min-width 指的是「容器本身的 inline-size」,而不是視窗的寬度。

知道如何使用容器查詢之後,讓我們回到上方範例,該如何調整,才能解決側欄跑版的問題?

點擊這個連結,可以看到完整範例結構。

該程式碼的 HTML 結構大致是這樣的:

<main class="main">
<div class="card">...</div>
<div class="card">...</div>
</main>

<aside class="sidebar">
<div class="card">...</div>
<div class="card">...</div>
</aside>

解決辦法很簡單,只要將響應式的依據設為卡片的父容器,也就是 .main 以及 .sidebar,就可以透過容器查詢處理響應式設計:

/* 宣告容器 */
.main,
.sidebar {
container-type: inline-size;
}

/* 容器查詢設定 */
@container (max-width: 800px) {
.card {
flex-direction: column;
}
.img-container {
aspect-ratio: 16/9;
}
}

修正完成後,應該就可以看到現在卡片的樣式是依據其容器寬度而定:

raw-image

命名容器(Container Name)

當畫面中的容器結構逐漸變得複雜,或出現多層容器巢狀時,單純依賴「最近的容器」可能會讓樣式關係變得不夠直觀。此時,可以透過 container-name 來替容器命名,明確指定查詢的對象。

設定容器名稱

.wrapper {
container-type: inline-size;
container-name: certain-container;
}

指定查詢容器

@container certain-container (min-width: 375px) {
/* certain-container 寬度 ≥ 375px 時的設計 */
}

透過命名容器,可以有效降低大型版型或元件系統中,樣式彼此影響的風險。

容器查詢單位(Container Query Units)

除了條件查詢之外,容器查詢也提供了一組對應於視窗單位的長度單位,其特徵是以 cq(container query)作為前綴,參照的基準則是「容器尺寸」而非視窗。

raw-image
cqi(inline-size)與 cqb(block-size)屬於邏輯尺寸單位。在一般水平書寫模式下,行為會分別對應到 cqwcqh,但在不同文字流向時仍具有其意義上的差異。

嵌套容器與查詢基準

需要特別留意的是,容器查詢單位採就近法則,是以最近的容器作為計算基準,這點即使有透過名稱,指定查詢其他容器也一樣

假設有以下容器嵌套結構:

<section class="father">
<div class="child">
<div class="card">...</div>
</div>
</section>
.father {
container-type: inline-size;
container-name: father;
}

.child {
container-type: inline-size;
container-name: child;
}

在這個情境中:

  • .card 可以透過 @container father,依據 .father 的寬度來切換樣式。
  • 但若在 .card 內使用 cqwcqi 等容器單位,實際參照的仍會是最近的 .child 容器,而非 .father

理解「查詢條件可以指定容器,但單位計算永遠取最近容器」這個差異,是實務上避免誤判版型行為的關鍵。

結語

容器查詢並不是要取代媒體查詢,而是補足其在「元件化設計」上的不足。當元件需要在不同版位、不同容器寬度下被重複使用時,容器查詢能夠讓樣式邏輯更加貼近實際版面結構,也更符合現代前端元件化的思維。

參考


留言
avatar-img
肝 code 人生
1會員
5內容數
2024 年 7 月開始的「肝 code 人生」,2025 年 1 月撰寫第一篇程式筆記
你可能也想看
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
本篇文章介紹了網頁元素的 Box 佈局,細述 Content Box、Padding Box、Border Box 和 Margin Box 的結構,並探討了 Intrinsic 與 Extrinsic Size 的特性。
Thumbnail
本篇文章介紹了網頁元素的 Box 佈局,細述 Content Box、Padding Box、Border Box 和 Margin Box 的結構,並探討了 Intrinsic 與 Extrinsic Size 的特性。
Thumbnail
data-* attributes 是 HTML 內建的屬性,可將網頁的狀態與元素進行綁定。而Tailwind CSS 在 3.2 版更新中推出使用 data-* attributes 自訂樣式的功能,讓樣式設定可以更動態多變。
Thumbnail
data-* attributes 是 HTML 內建的屬性,可將網頁的狀態與元素進行綁定。而Tailwind CSS 在 3.2 版更新中推出使用 data-* attributes 自訂樣式的功能,讓樣式設定可以更動態多變。
Thumbnail
相信透過之前的介紹,大家對於 CSS 選擇器(CSS selector)已經不陌生了,今天我們要來聊聊兩個在實務上非常好用的偽類(pseudo class )語法,他們分別是 :nth-child() 與 :nth-of-type(),在了解這兩個語法之前,我們首先要先來聊聊什麼是「偽類」呢?
Thumbnail
相信透過之前的介紹,大家對於 CSS 選擇器(CSS selector)已經不陌生了,今天我們要來聊聊兩個在實務上非常好用的偽類(pseudo class )語法,他們分別是 :nth-child() 與 :nth-of-type(),在了解這兩個語法之前,我們首先要先來聊聊什麼是「偽類」呢?
Thumbnail
不論是在基礎或是進階的版面排列,幾乎離開不了 position 系列的 CSS 語法,如果對於這些語法不熟悉,要快速完成畫面需求幾乎是不可能的,甚至會延宕整個團隊的開發速度(對,position 語法就是這麽重要)。
Thumbnail
不論是在基礎或是進階的版面排列,幾乎離開不了 position 系列的 CSS 語法,如果對於這些語法不熟悉,要快速完成畫面需求幾乎是不可能的,甚至會延宕整個團隊的開發速度(對,position 語法就是這麽重要)。
Thumbnail
相信大家在一開始接觸 CSS 時,一定會很疑惑為什麼除了 width 外,還會有 max-width 及 min-width 語法呢? 當要開發響應式網頁時,到底要使用什麼語法來控制「斷點」?
Thumbnail
相信大家在一開始接觸 CSS 時,一定會很疑惑為什麼除了 width 外,還會有 max-width 及 min-width 語法呢? 當要開發響應式網頁時,到底要使用什麼語法來控制「斷點」?
Thumbnail
對於前端初學者來說,在切版時會出現很多規則、不規則的網頁區塊,這時候我們會嘗試用各種相對定位、絕對定位、margin 或是 padding 的方式來進行網頁區塊的推擠。
Thumbnail
對於前端初學者來說,在切版時會出現很多規則、不規則的網頁區塊,這時候我們會嘗試用各種相對定位、絕對定位、margin 或是 padding 的方式來進行網頁區塊的推擠。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News