1270 字
6 分鐘

CSS overflow: auto clip 怎麼用?單軸捲動與 sticky 邊界

很多水平卡片、表格或畫布元件,其實只需要左右捲動;但常見的 overflow: auto 會讓上下軸也成為可捲動軸,overflow: hidden 又可能讓 position: sticky 找到你不想要的祖先。結果就是 header 不再貼住預期位置,或觸控手勢在巢狀容器間互相搶事件。

直接答案是:水平元件先用 overflow: auto clip 表達「inline 軸可捲動、另一軸只裁切」;針對要允許斜向手勢的地圖或放大圖片,再評估 scroll-axis-lock: none。兩者目前都不該被當成所有瀏覽器都已支援的 production 基線。

Chrome 153 release notes 將 single-axis scroll containers 標示為非穩定 channel 功能;scroll-axis-lock 也來自 CSS Overflow Level 5 的新規範。請把 feature detection、fallback 與真實裝置測試一起納入元件設計。

先分清楚三種 overflow 意圖#

寫法主要意圖常見代價
overflow: auto兩軸都可能需要捲動產生不必要的第二個 scroll axis,sticky 邊界較難推理
overflow: hidden隱藏溢出內容可能建立你不想要的滾動祖先,且鍵盤或程式捲動行為容易被誤判
overflow: auto clip一軸可捲動,另一軸裁切新語法仍需檢查瀏覽器支援與 fallback

這不是把內容「藏起來」的視覺技巧,而是把 scrollability 寫進 layout contract。你要先決定哪一個軸真的可以被使用者操作,再選擇 CSS。

水平卡片用 auto clip#

先建立不依賴特定框架的 HTML:

<section class="board" aria-labelledby="board-title">
<h2 id="board-title" class="board__title">功能總覽</h2>
<div class="board__track">
<article class="card">第一張卡片</article>
<article class="card">第二張卡片</article>
<article class="card">第三張卡片</article>
</div>
</section>

如果是整個 board 負責水平捲動,最小配置可以是:

.board {
overflow: auto clip;
overscroll-behavior-inline: contain;
}
.board__track {
display: flex;
gap: 1rem;
inline-size: max-content;
min-inline-size: 100%;
}
.card {
flex: 0 0 min(80vw, 24rem);
}

overflow shorthand 在常見的水平 LTR 寫法中,第一個值對應 x 軸、第二個值對應 y 軸;auto clip 因此代表 x 可捲動、y 裁切。若元件需要支援不同 writing mode,請把這段意圖改寫成 overflow-inline: autooverflow-block: clip,並實際檢查瀏覽器對 logical properties 的支援。

如果內容只應該在 x 軸移動,也可以把物理軸寫得更直白:

.board {
overflow-x: auto;
overflow-y: clip;
}

這種寫法適合先表達設計意圖,但不能跳過 @supports 與 fallback 測試;新舊瀏覽器對「一軸 scrollable、另一軸 clip」的處理可能不同。

為什麼它能幫 sticky 少走錯路#

position: sticky 不是固定在 viewport;它會受祖先的 scroll container、inset 與可用空間限制。當外層只因為 overflow: auto 意外建立 y 軸 scroll container,sticky header 可能就跟著錯誤的祖先計算。

一個簡化的 header 範例:

.board__title {
position: sticky;
inset-block-start: 0;
z-index: 1;
background: Canvas;
}

auto clip 的價值,是讓 layout 明確表示某一軸只能裁切,瀏覽器才有機會把 sticky 的不同軸邊界分開計算。但它不會自動修好所有 sticky 問題;仍要檢查祖先是否有 transform、contain、額外的 overflow、固定高度與 stacking context。

排錯時先在 DevTools 逐層暫時移除 overflow,再確認是哪一個祖先在目標軸真的可捲動。不要只把 z-index 調大,因為那通常解不了錯誤的 scroll ancestor。

scroll-axis-lock 適合另一種互動#

瀏覽器常會把觸控捲動手勢鎖到主要移動軸,避免使用者想左右滑時不小心上下漂移。CSS Overflow Level 5 的 scroll-axis-lock 允許作者在需要「斜向也能持續捲動」的 scroll container 上關閉這個鎖定:

.map-or-zoomed-image {
scroll-axis-lock: none;
}

這比較適合地圖、放大圖片或需要同時操作兩軸的畫布,不是一般水平 carousel 的預設值。普通卡片列通常應保留軸向鎖定,讓觸控操作更容易預期。

Feature detection 與 fallback#

不要只以 user agent 判斷;用 CSS capability check,並準備視覺與互動都可接受的 fallback:

.board {
overflow-x: auto;
overflow-y: hidden;
}
@supports (overflow: auto clip) {
.board {
overflow: auto clip;
}
}
@supports (scroll-axis-lock: none) {
.map-or-zoomed-image {
scroll-axis-lock: none;
}
}

fallback 使用 hidden 時,語意不等同於 clip;它可能仍參與 scroll container 計算。因此 fallback 的目標是讓舊瀏覽器能操作,而不是假裝兩種行為完全一樣。若 sticky 是核心需求,請在 fallback browser 上單獨驗收 header 邊界。

上線前的四組測試#

  1. 滑鼠與觸控:水平拖曳不會把頁面垂直位置帶走;需要雙軸的地圖仍能斜向操作。
  2. 鍵盤:focus 進入卡片後,Tab、方向鍵與可見 focus ring 都能到達被裁切內容。
  3. sticky:在短內容、長內容、巢狀 overflow、縮放與不同 viewport 高度逐一檢查。
  4. 支援矩陣:至少測試 stable browser、Chrome 153 對應的實驗 channel、iOS/Android 觸控與沒有新語法的 fallback。

如果元件還需要 snap、marker 或按鈕導覽,可以接著看 CSS Scroll Marker 建立可存取輪播導覽;不要把實驗中的 marker API 與單軸 overflow 當成同一個功能。

參考資料:

Chrome for Developers:Chrome 153 release notes

W3C CSS Overflow Module Level 5:Scroll Axis Locking

MDN:CSS overflow carousels

CSS overflow: auto clip 怎麼用?單軸捲動與 sticky 邊界
https://laplusda.com/posts/css-single-axis-scroll-container/
作者
Zero
發佈於
2026-09-12
許可協議
CC BY-NC-SA 4.0
這篇文章有幫助嗎?

回報錯字、失效連結,或告訴我你想看的延伸主題。