跳至主要內容

CSS Container Queries:響應式設計的新時代

CSS Container Queries:響應式設計的新時代

長久以來,CSS Media Queries 是我們實作響應式設計的唯一標準工具。但它有一個根本限制:它只能感知視窗(viewport)的寬度,而無法感知元件容器的大小。Container Queries 的出現解決了這個問題,讓我們終於可以做到真正的「元件級響應式設計」。

Media Queries 的問題

假設你有一個卡片元件,在寬螢幕側欄和主要內容區都會用到:

/* 傳統做法:根據視窗寬度調整 */
.card { display: block; }

@media (min-width: 768px) {
  .card { display: flex; }
}

但問題是,同一個卡片在 1200px 的視窗中,放在側欄(寬 300px)和主區(寬 800px)的版面需求完全不同。Media Queries 無法區分這兩種情況。

Container Queries 基本語法

/* 步驟一:定義容器 */
.card-wrapper {
  container-type: inline-size;
  container-name: card-container; /* 可選,建議加上 */
}

/* 步驟二:在容器內使用 @container */
@container card-container (min-width: 400px) {
  .card {
    display: flex;
    gap: 16px;
  }

  .card-image {
    width: 160px;
    flex-shrink: 0;
  }
}

container-type 有三個值:

  • inline-size:只監聽行內軸(通常是寬度)的大小變化
  • size:監聽寬度和高度
  • normal:只能使用樣式查詢,不能使用尺寸查詢

實際案例:自適應卡片元件

<div class="grid">
  <div class="card-wrapper">
    <article class="card">
      <img class="card-image" src="..." alt="">
      <div class="card-content">
        <h3 class="card-title">文章標題</h3>
        <p class="card-excerpt">文章摘要...</p>
        <a class="card-link" href="#">閱讀更多</a>
      </div>
    </article>
  </div>
</div>
.card-wrapper {
  container-type: inline-size;
  container-name: card;
}

/* 窄版:垂直排列 */
.card {
  display: block;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid #e2e8f0;
}

.card-image {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.card-content {
  padding: 16px;
}

.card-title {
  font-size: 1rem;
}

/* 中版(容器 >= 400px):水平排列 */
@container card (min-width: 400px) {
  .card {
    display: flex;
    align-items: stretch;
  }

  .card-image {
    width: 180px;
    aspect-ratio: auto;
    flex-shrink: 0;
  }

  .card-title {
    font-size: 1.125rem;
  }
}

/* 寬版(容器 >= 600px):更大的圖片和字體 */
@container card (min-width: 600px) {
  .card-image {
    width: 240px;
  }

  .card-title {
    font-size: 1.25rem;
  }

  .card-content {
    padding: 24px;
  }
}

容器查詢單位

Container Queries 引入了新的長度單位:

@container (min-width: 400px) {
  .card-title {
    /* cqw:容器寬度的百分比 */
    font-size: clamp(1rem, 3cqw, 1.5rem);

    /* cqi:容器 inline-size 的百分比 */
    padding: 2cqi;

    /* cqb:容器 block-size 的百分比 */
    /* cqmin:cqi 和 cqb 中較小的 */
    /* cqmax:cqi 和 cqb 中較大的 */
  }
}

Style Queries(樣式查詢)

這是更進階的功能,可以根據容器的 CSS 自訂屬性來調整樣式:

.card-wrapper {
  container-type: normal; /* 不需要 inline-size */
  --card-theme: dark;
}

@container style(--card-theme: dark) {
  .card {
    background: #1a202c;
    color: white;
  }

  .card-title {
    color: #f6e05e;
  }
}

搭配 Tailwind CSS

Tailwind CSS v3.2+ 已支援 Container Queries(需安裝插件):

npm install @tailwindcss/container-queries
// tailwind.config.js
module.exports = {
  plugins: [
    require('@tailwindcss/container-queries'),
  ],
};
<div class="@container">
  <div class="flex flex-col @md:flex-row gap-4">
    <img class="w-full @md:w-48" src="..." alt="">
    <div>
      <h3 class="text-base @lg:text-xl">標題</h3>
      <p>內容</p>
    </div>
  </div>
</div>

瀏覽器支援

截至 2025 年,所有現代瀏覽器均已完整支援 Container Queries(Chrome 105+, Firefox 110+, Safari 16+)。

與 Media Queries 的搭配策略

Container Queries 並不是要取代 Media Queries,而是互補:

/* Media Queries:控制整體頁面佈局 */
@media (min-width: 1024px) {
  .layout {
    grid-template-columns: 300px 1fr;
  }
}

/* Container Queries:控制元件內部樣式 */
@container sidebar (min-width: 280px) {
  .nav-item {
    display: flex;
    align-items: center;
    gap: 8px;
  }
}

總結

Container Queries 是 CSS 響應式設計的重大突破。它讓元件能夠根據自身所在容器的大小調整樣式,而不是依賴全域的視窗尺寸。這使得元件真正具備了「可攜性」——放在任何容器中都能呈現最佳外觀。隨著瀏覽器支援已相當完整,現在正是將 Container Queries 納入日常開發工具箱的好時機。

分享這篇文章