搜尋

CSS @container 容器查詢 ( Container Queries )

CSS 的 @container 容器查詢和 @media 媒體查詢類似,都可以在判斷出指定條件時,針對特定的元素套用特定的樣式,但有別於 @media 是根據頁面判斷,CSS 的 @container 是根據「容器」進行判斷,這篇教學會介紹 CSS @container 容器查詢 ( Media Queries ) 的相關用法。

快速導覽:

CSS 教學 - @container 容器查詢 ( Container Queries )

認識與使用 @container

CSS 的 @container 顧名思義就是針對「容器 container」所定義的 At 規則,透過特定的邏輯判斷,當「容器」符合特定的條件時,就會對「容器裡的元素」套用特定的樣式,使用時需要先建立一個「容器」,只有在容器裡的元素才會套用 @container 所定義的規則

當元素設定了 container-type 樣式屬性,這個元素就會變成「容器 container」

下方的範例會在容器寬度大於 400px 時,將 .container 裡的 h2 字體放大 ( .container 設定了 container-type: inline-size; 變成容器類型 )。

線上展示:https://codepen.io/oxxo/pen/jENxGOO

<!-- HTML 程式碼 -->
<div class="container">
  <h2>apple</h2><h2>banana</h2><h2>oxxo</h2>
</div>
<div>
  <h2>apple</h2><h2>banana</h2><h2>oxxo</h2>
</div>

<!-- CSS 程式碼 -->
<style>
  @container (width > 400px) {
    h2 {font-size: 50px;}  /* 容器寬度大於 400px 時,裡面的 h2 會變成 50px */
  }
  div {
    border: 1px solid #000;
    margin: 20px;
  }
  h2 {margin: 0;}
  .container {container-type: inline-size;}  /* 這個元素變成容器類型 */
</style>

CSS 教學 - @container 容器查詢 ( Container Queries ) - 認識與使用 @container

容器類型 container-type

使用 container-type 所建立的容器有下列幾種類型:

容器類型 說明
normal 預設值,不透過 @container 來判斷處理。
inline-size 由「寬度」定義條件,容器高度由「內容」決定,最常使用的設定。
size 由「寬度與高度」定義條件,容器高度需要「手動」設定。

下方的範例使用三個 div 分別表現三種容器類型,可以看出設定 normal 的容器完全不受 @container 影響,設定 inline-size 的容器高度由內容決定,設定 size 的容器沒有高度,導致內容外的 footer 元素和容器內容重疊。

線上展示:https://codepen.io/oxxo/pen/mybLBbG

<!-- HTML 程式碼 -->
<div class="notmal">
  <h2>container-type: normal;</h2>
</div>
<div class="inline-size">
  <h2>container-type: inline-size;</h2>
</div>
<div class="size">
  <h2>container-type: size;</h2>
</div>
<footer>我是結尾</footer>

<!-- CSS 程式碼 -->
<style>
  @container (width > 400px) {
    h2 {font-size: 50px;}
  }
  div {
    border: 1px solid #000;
    margin: 20px 0;
  }
  h2 {margin: 0;}
  footer {background: #f005;}

  .notmal {container-type: normal;}
  .inline-size {container-type: inline-size}
  .size {container-type: size;}
</style>

CSS 教學 - @container 容器查詢 ( Container Queries ) - 容器類型 container-type

容器名稱 container-name

如果網頁中有多個容器,則可以使用 container-name 替容器命名,並在 @container 中針對特定名稱的容器定義樣式,容器名稱可以使用英文字母大小寫、阿拉伯數字、連結線、底線 ( 開頭不為數字 ),寫法為:

@container 名稱 ( 判斷 ) {
  ......
}

下方範例會將三個 div 設定為容器,並分別命名為「aaa、bbb、ccc」,接著使用 @container 設定在不同寬度時會放大與變色。

線上展示:https://codepen.io/oxxo/pen/LEPmzYe

<!-- HTML 程式碼 -->
<div class="rr">
  <h2>寬度 > 500px 時,變紅變大</h2>
</div>
<div class="bb">
  <h2>寬度 > 450px 時,變藍變大</h2>
</div>
<div class="gg">
  <h2>寬度 > 400px 時,變綠變大</h2>
</div>

<!-- CSS 程式碼 -->
<style>
  @container rrr (width > 500px) {
    h2 {
      color: red;
      font-size: 30px;
    }
  }
  @container bbb (width > 450px) {
    h2 {
      color: blue;
      font-size: 30px;
    }
  }
  @container ggg (width > 400px) {
    h2 {
      color: green;
      font-size: 30px;
    }
  }
  div {
    border: 1px solid #000;
    margin: 20px 0;
    container-type: inline-size;
  }
  h2 {margin: 0;}

  .rr {container-name: rrr;}  /* 這個元素的容器名稱為 rrr */
  .gg {container-name: ggg;}  /* 這個元素的容器名稱為 ggg */
  .bb {container-name: bbb;}  /* 這個元素的容器名稱為 bbb */
</style>

CSS 教學 - @container 容器查詢 ( Container Queries ) - 容器名稱 container-name

容器縮寫格式 container

container 樣式為 container-namecontainer-type 的縮寫格式,使用「斜線 /」分隔這兩個樣式屬性的屬性值,如果只有一個屬性值則代表 container-name相關寫法如下:

div {
  container: container-name / container-type;  /* 名稱在前,類型在後 */
  container: container-name;
}

下方範例會將前一個小節的範例,改成 container 的寫法。

線上展示:https://codepen.io/oxxo/pen/OPLZepX

<!-- HTML 程式碼 -->
<div class="rr">
  <h2>寬度 > 500px 時,變紅變大</h2>
</div>
<div class="bb">
  <h2>寬度 > 450px 時,變藍變大</h2>
</div>
<div class="gg">
  <h2>寬度 > 400px 時,變綠變大</h2>
</div>

<!-- CSS 程式碼 -->
<style>
  @container rrr (width > 500px) {
    h2 {
      color: red;
      font-size: 30px;
    }
  }
  @container bbb (width > 450px) {
    h2 {
      color: blue;
      font-size: 30px;
    }
  }
  @container ggg (width > 400px) {
    h2 {
      color: green;
      font-size: 30px;
    }
  }
  div {
    border: 1px solid #000;
    margin: 20px 0;
  }
  h2 {margin: 0;}

  .rr {container: rrr / inline-size;}  /* 這個元素的容器名稱為 rrr */
  .gg {container: ggg / inline-size;}  /* 這個元素的容器名稱為 ggg */
  .bb {container: bbb / inline-size;}  /* 這個元素的容器名稱為 bbb */
</style>

CSS 教學 - @container 容器查詢 ( Container Queries ) - 容器縮寫格式 container

容器查詢語法 ( 媒體 media queries )

@container 最基本的查詢撰寫方式與 @media 類似,可以根據瀏覽器的寬高、尺寸比例等媒體訊息進行判斷,判斷時可使用「or、and、not」等邏輯判斷語法,邏輯判斷的條件基本上和 @media 的「媒體特色 ( Media Features )」相同,下方列出支援的寫法:

更多參考:媒體特色 ( Media Features )

@container (條件) {...}               /* 滿足單一條件 */
@container (條件 1), (條件 2) {...}    /* 滿足條件 1 或條件 2 其中一項 ( or 寫法 ) */
@container (條件 1) and (條件 2) {...} /* 同時滿足條件 1 與條件 2 ( and 寫法 ) */
@container not (條件) {...}           /* 不滿足單一條件,不可與 and 和 or 混用 */

下方範例使用四個容器,分別呈現四種不同的查詢語法。

線上展示:https://codepen.io/oxxo/pen/wBwjrvb

<!-- HTML 程式碼 -->
<div class="rr">
  <h2>寬度 > 500px 時,變紅變大</h2>
</div>
<div class="bb">
  <h2>寬度 > 500px 或寬度 < 400px 時,變藍變大</h2>
</div>
<div class="gg">
  <h2>寬度 > 400px 且寬度 < 500px 時,變綠變大</h2>
</div>
<div class="oo">
  <h2>寬度沒有 > 400px 時,變橘變大</h2>
</div>

<!-- CSS 程式碼 -->
<style>
  @container rrr (width > 500px){
    h2 {
      color: red;
      font-size: 30px;
    }
  }
  @container bbb (width > 500px) or (width < 400px) {
    h2 {
      color: blue;
      font-size: 30px;
    }
  }
  @container ggg (width > 400px) and (width < 500px)  {
    h2 {
      color: green;
      font-size: 30px;
    }
  }
  @container ooo not (width > 400px)  {
    h2 {
      color: orange;
      font-size: 30px;
    }
  }
  div {
    border: 1px solid #000;
    margin: 20px 0;
    container-type: inline-size;
  }
  h2 {margin: 0;}

  .rr {container-name: rrr;}
  .gg {container-name: ggg;}
  .bb {container-name: bbb;}
  .oo {container-name: ooo;}
</style>

CSS 教學 - @container 容器查詢 ( Container Queries ) - 容器查詢語法 ( 媒體 )

容器查詢語法 ( 樣式 style queries )

@container 除了可以根據媒體的狀態將容器套用對應樣式,也可以使用 style() 樣式查詢的方式,「判斷容器是否具有特定樣式」,進而套用指定的樣式,查詢判斷可以和媒體狀態互相搭配,並使用「or、and、not」等邏輯判斷語法,關寫法如下:

注意,目前這個查詢語法「只支援變數和自訂屬性」,且一個 style() 裡只能放入一組樣式,若判斷具有該樣式則回傳 true,沒有則回傳 false。

/* 目前不支援,未來可能支援的寫法 */
@container style(color: red) {...}                            /* 容器具有 color: red */
@container style(color: red) and style(font-size: 20px) {...} /* 容器同時具有 color: red 和 font-szie: 20px */

/* 目前支援 */
@container style(--oxxo: true) {...}              /* 容器具有變數 --oxxo: true 樣式和屬性值 */
@container style(--a: 1) and style(--b: 2) {...}  /* 容器同時變數 --a: 1 和 --b: 2 樣式和屬性值 */

下方範例使用四個容器,呈現使用 style() 的查詢語法。

線上展示:https://codepen.io/oxxo/pen/pvzVBYz

<!-- HTML 程式碼 -->
<div class="r">
  <h2>變紅 style(--oxxo: 1)</h2>
</div>
<div class="g">
  <h2>變綠 style(--oxxo: 1) and style(--xoox: 1)</h2>
</div>
<div class="b">
  <h2>變藍 style(--oxxo: 1) and style(--xoox: 2)</h2>
</div>
<div class="o">
  <h2>沒有設定不會變色</h2>
</div>

<!-- CSS 程式碼 -->
<style>
  @container style(--oxxo: 2){
    h2 {background: orange;}  /* 如果容器裡有 --oxxo: 2 */
  }
  @container style(--oxxo: 1){
    h2 {color: red;}          /* 如果容器裡有 --oxxo: 1 */
  }
  @container style(--oxxo: 1) and style(--xoox: 1){
    h2 {color: green;}        /* 如果容器裡有 --oxxo: 1 和 --xoox: 1 */
  }
  @container style(--oxxo: 1) and style(--xoox: 2){
    h2 {color: blue;}         /* 如果容器裡有 --oxxo: 1 和 --xoox: 2 */
  }
  div {
    container-type: inline-size;
  }

  .r {
    --oxxo: 1;
  }
  .g {
    --oxxo: 1;
    --xoox: 1;
  }
  .b {
    --oxxo: 1;
    --xoox: 2;
  }
  div[class]:hover {
    --oxxo: 2;   /* 滑鼠移動到 .r .g .b 三個 div 上方時, --oxxo 改為 2 */
  }
</style>

CSS 教學 - @container 容器查詢 ( Container Queries ) - 容器查詢語法 ( 樣式 )

容器查詢特殊單位

當元素轉換成容器後,在元素裡就可以使用下方列出的特殊單位:

單位 說明
cqw 1% container 的 width。
cqh 1% container 的 height。
cqi 1% container 的 inline-size。
cqb 1% container 的 block-size。
cqmin cqi 與 cqb 的最小值。
cqmax cqi 與 cqb 的最大值。

線上展示:https://codepen.io/oxxo/pen/EaYLJMg

<!-- HTML 程式碼 -->
<div class="rr">
  <h2>寬度 > 400px 時,變紅,尺寸為容器的一半</h2>
</div>
<div class="bb">
  <h2>寬度 > 400px 時,變藍,尺寸為容器的 80%</h2>
</div>
<div class="gg">
  <h2>寬度 > 400px 時,變綠</h2>
</div>

<!-- CSS 程式碼 -->
<style>
  @container rrr (width > 400px) {
    /* 注意前方使用 div h2 避免權重被後方覆蓋 */
    div h2 {
      color: red;
      width: 50cqi;
    }
  }
  @container bbb (width > 400px) {
    /* 注意前方使用 div h2 避免權重被後方覆蓋 */
    div h2 {
      color: blue;
      width: 80cqi;
    }
  }
  @container ggg (width > 400px) {
    div h2 {color: green;}
  }
  div {
    border: 1px solid #000;
    margin: 20px 0;
    container-type: inline-size;
  }
  h2 {
    margin: 0;
    width: 200px;
    background: orange;
  }

  .rr {container-name: rrr;}  /* 這個元素的容器名稱為 rrr */
  .bb {container-name: bbb;}  /* 這個元素的容器名稱為 bbb */
  .gg {container-name: ggg;}  /* 這個元素的容器名稱為 ggg */
</style>

CSS 教學 - @container 容器查詢 ( Container Queries ) - 容器查詢特殊單位

小結

@container 是一個新的 CSS 定義,在舊版的瀏覽器或部分ㄓ Firebox 上並不支援,但如果不考慮這些瀏覽器,@container 對於 RWD 響應式網頁而言,是個相當不錯的功能,如果有機會不妨使用看看吧。

意見回饋

如果有任何建議或問題,可傳送「意見表單」給我,謝謝~

CSS 教學

基本介紹

認識 CSS 開始使用 CSS CSS 語法規則 CSS 命名原則 CSS 常用樣式屬性

CSS 選擇器

認識 CSS 選擇器 優先順序 ( 權重 ) 樣式繼承與聯集 使用巢狀結構語法 元素選擇器 ID 和 Class 選擇器 屬性選擇器 文件結構選擇器 虛擬類別選擇器 ( 結構 ) 虛擬類別選擇器 ( 類型 ) 虛擬類別選擇器 ( 輸入 ) 虛擬類別選擇器 ( 行為 ) 虛擬類別選擇器 ( 超連結 ) 虛擬類別選擇器 ( 邏輯 ) 虛擬類別選擇器 ( 其他 ) 虛擬元素選擇器 群組與組合選擇器

數值與單位

關鍵字與文字數值 長度與角度單位 位置名稱與時間單位

規則與定義

變數 ( Variables ) 媒體查詢 ( @media ) 容器查詢 ( @container ) 自訂屬性值 ( @property ) 匯入樣式 ( @import ) 分層優先順序 ( @layer )

函式類型

數學計算 文字與清單計數 形狀與線段 路徑 ( path ) 生成內容與引號

顏色與濾鏡

顏色單位 色彩模型 漸層色 影像濾鏡 ( filter ) 背景濾鏡 ( backdrop-filter ) 混合模式 ( mix-blend-mode )

文字與段落

設定字型 ( font-family ) 使用外部字型 定義字型 ( @font-face ) 文字尺寸 文字樣式 ( 常用 ) 文字樣式 ( 其他實用 ) 文字樣式 ( 特殊用途 ) 文字換行 文字空白與 Tab 大小 文字行高與縮排 文字水平與垂直對齊 文字書寫方向 文字自動分欄

元素容器

容器顯示類型 ( display ) 元素 display 對照表 盒子模型 ( Box Model ) 寬度與高度 內邊距 ( padding ) 外邊界 ( margin ) 邊框 ( border ) 邊框圓角 ( border-radius ) 影像邊框 ( border-image ) 輪廓 ( outline ) 內容溢出與裁切 ( overflow ) 內容範圍 ( contain ) 可見性與透明度

背景與陰影

背景顏色 背景圖 ( 定位、尺寸 ) 背景圖 ( 固定、重複 ) 背景圖 ( 多重背景、混合 ) 背景縮寫 ( background ) 容器陰影 ( box-shadow )

清單與表格

清單樣式 清單計數器 定義計數規則 表格基本樣式 表格邊框樣式 表格內容寬度與對齊

基本排版與定位

元素排版方式 浮動 ( float ) 浮動形狀 定位 ( position )

Flexbox 彈性排版

Flexbox 彈性盒子 Flexbox 對齊方式 Flexbox 彈性伸縮

Grid 網格排版

Grid 網格容器與格線 Grid 網格空間與命名 Grid 網格流向與間距 Grid 排列網格項目 Grid 項目對齊與順序

轉場與動畫

轉場 ( transition ) 轉場觸發事件 動畫 ( animation ) 自訂動畫路徑 ( offset ) 動畫觸發事件 多重動畫的權重與順序

變形、裁切與遮罩

裁切路徑 ( clip-path ) 影像遮罩 ( mask ) 物件填滿方式與定位 轉換函式 ( transform ) 平移、旋轉與縮放 3D 轉換與透視 3D 正多面體

視窗與使用者行為

捲軸樣式 ( scrollbar ) 滑鼠游標圖示 ( cursor ) 滑鼠事件 ( pointer-events ) 使用者選取 ( user-select ) 捲動行為 ( scroll、overscroll )

範例效果

CSS 圓餅圖 CSS 跑馬燈 Google 載入動畫 漸層色的轉場與動畫 電子時鐘數字 不規則形狀動畫