← 回到 Blog
前端開發約 3 分鐘閱讀

CSS Container Query 版面巡檢:把卡片寬度、圖片比例與內容密度留成證據

分類前端開發CSS網站經營
標籤#CSS#Container Query#RWD#Frontend QA#版面驗收#內容網站
CSS Container Query 版面巡檢 cover,顯示響應式卡片、@container 程式碼、DevTools 尺寸標記與手機版面驗收

內容網站常見的 RWD 問題,不一定來自整個 viewport,而是來自「某個模組被放到不同容器後失去比例」。同一張文章卡片在首頁 Hero 旁邊、Blog 列表、分類頁或側欄中,可能拿到完全不同的可用寬度。這時只靠 @media 斷點會越寫越多,因為真正需要反應的是容器,不是螢幕。

CSS Container Query 可以讓卡片依照父層容器調整圖片比例、標題行數、摘要顯示與 CTA 密度。不過它不是導入後就自動變好的魔法。對 UCAMC 這類長期內容站,我會把 Container Query 視為一個需要留證據的版面變更:先記錄目前問題,再套用最小 CSS,最後確認桌面、平板、手機與 Blog 卡片都沒有破版。

先記錄容器,而不是只記錄 viewport

導入前先把問題說清楚。不要只寫「手機版不好看」,而是記錄哪一個容器、哪一張卡片、哪一段文字造成密度或 overflow。

Observe
- page: /blog
- module: post-list-card
- viewport: 390px
- container width: 342px
- symptom: title wraps to 4 lines and pushes CTA below fold
- image: 16:9 is fine, but excerpt is too long for narrow card

如果問題發生在首頁最新文章卡片,也要另外記錄,因為首頁 grid 的容器寬度可能跟 /blog 完全不同。

Observe
- page: /
- module: latest-grid .post-card
- viewport: desktop 1440px
- container width: 368px
- symptom: card height differs because excerpt length varies

這些資料會決定要用 Container Query、一般 media query,還是單純調整內容摘要。

最小可回滾的 CSS 寫法

比較安全的做法,是先讓卡片成為容器,再針對卡片內部元素調整,而不是重寫整個 layout。

.post-card,
.post-list-card {
  container-type: inline-size;
  container-name: article-card;
}

@container article-card (max-width: 360px) {
  .post-card h2,
  .post-list-card h2 {
    font-size: 1.05rem;
    line-height: 1.35;
  }

  .post-card p,
  .post-list-card p {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
}

我會避免一開始就把所有卡片高度寫死。內容站的文章標題本來就有長短,過度固定高度容易讓中文標題被切得不自然。先處理最明顯的密度問題,再用實際頁面驗收。

圖片比例也要跟著巡檢

Container Query 常被拿來調整文字,但卡片圖片也需要一起看。首頁精選卡、Blog 列表卡與分類頁卡片如果共用資料來源,至少要確認這三件事:

  • coverImagefeaturedImage 是否存在。
  • coverAlt 是否描述文章主題,而不是泛用圖片文字。
  • 圖片容器是否維持穩定比例,載入後不造成 layout shift。

可以把圖片驗收寫成這樣:

Image evidence
- file: /images/blog/frontend-css-container-query-layout-audit-cover.png
- response: 200 image/png
- rendered article image: naturalWidth > 0
- Blog card: image is visible and object-fit cover
- OG image: meta property og:image points to the same topic image

這份紀錄比「有一張圖」更有價值,因為它同時檢查了內容、品牌與 SEO 顯示。

手機驗收:先找 page-level overflow

手機版最容易誤判。程式碼區塊、長英文 tag、URL 或表格,都可能在局部超出;但真正會影響讀者的是整頁是否產生水平捲動。驗收時我會先看 page-level,再看局部可捲動區塊。

const root = document.documentElement;
const pageOverflow = root.scrollWidth > root.clientWidth;

const offenders = [...document.querySelectorAll('main *')]
  .map((node) => {
    const rect = node.getBoundingClientRect();
    return {
      tag: node.tagName,
      className: node.className,
      right: Math.round(rect.right),
      width: Math.round(rect.width),
    };
  })
  .filter((item) => item.right > root.clientWidth + 1);

pre 內的 code 比容器寬,且 pre 本身可以水平捲動,這通常不是整頁破版。反過來說,如果 documentElement.scrollWidth 大於 clientWidth,就要先處理造成整頁 overflow 的元素。

驗收表:Observe / Change / Verify

我會把 Container Query 改動寫成三段,方便未來回頭查:

Observe
- Blog card at 390px: title and excerpt create dense layout
- No root route issue; problem is presentation only

Change
- Add container-type to article cards
- Clamp excerpt only inside narrow card containers
- Keep desktop card typography unchanged

Verify
- / returns 200
- /blog returns 200 and latest card remains readable
- /frontend-css-container-query-layout-audit returns 200
- 390px page scrollWidth equals clientWidth
- cover image and og:image both use topic-specific image

這樣的紀錄能避免兩種常見錯誤:一是把 layout 小問題擴大成整站改版;二是只看桌面截圖就宣布手機版完成。

什麼情況不要急著用 Container Query

Container Query 很好用,但不是每個問題都該用它解。以下情況我會先選別的方法:

  • 問題只發生在單一文章標題太長:先調整 Hero 可見標題或摘要。
  • 問題來自圖片主題不符:先換對應文章主題的 cover。
  • 問題是全站主要內容字級太小:先做 main content typography 規則。
  • 問題是舊文章 Markdown 有超長裸露 URL:先做內容整理或 code block 換行。

Container Query 最適合解決「同一元件在不同容器寬度下需要不同密度」的問題。只要這個前提成立,它就能讓內容站的卡片更穩定,也更容易長期維護。

結語

對技術 Blog 來說,前端版面不是只追求漂亮,而是要讓讀者在首頁、Blog 列表、分類頁與文章頁都能穩定閱讀。Container Query 的價值在於讓元件回應自己的空間;維護者的責任則是把導入前後的證據留下來。

下一次調整卡片或首頁模組時,不妨先問:這是 viewport 問題,還是 container 問題?如果答案是後者,就用小範圍 Container Query 加上 route、圖片、OG 與手機 overflow 驗證,讓版面改善成為可追蹤的維護紀錄。