CSS 捲軸一出現版面就擠窄?用 scrollbar-gutter 預留空間

商品清單第一次只載入幾筆,按「載入更多」後,面板右側出現捲軸,卡片也突然變窄。若面板外框寬度沒變,先量一下它的 clientWidth。傳統捲軸會占用空間,內容可用的寬度可能因此縮小。

讓清單先留出捲軸的位置

把 scrollbar-gutter: stable 加到真正負責捲動的元素。下面的面板超過 12rem 才需要捲動。在使用傳統捲軸的環境,內容很少時也會保留同一條空間,等資料變多,捲軸就有地方可放。

.results {
  max-height: 12rem;
  overflow-y: auto;
  scrollbar-gutter: stable;
}

若清單是放在彈窗裡,先看開發者工具中哪一層的 scrollHeight 大於 clientHeight,再核對那一層的 overflow-y。把屬性加在清單外框或個別卡片上,通常不會改到實際捲動區。

用兩種資料量確認寬度

把這段另存成 HTML,用桌面瀏覽器開啟。點按鈕在 2 筆與 20 筆之間切換,觀察面板內側的寬度與是否溢出。先用預設的 auto,再把它改為 stable 重試。

<button type="button">切換清單長度</button>
<div class="results"></div>
<output></output>
<style>
  .results {
    width: min(100%, 320px);
    max-height: 120px;
    overflow-y: auto;
    scrollbar-gutter: auto;
    border: 1px solid #777;
  }
  .results p { margin: 0; line-height: 32px; }
</style>
<script>
  const box = document.querySelector('.results');
  const output = document.querySelector('output');
  let count = 2;
  function render() {
    box.replaceChildren(...Array.from({ length: count }, (_, i) => {
      const row = document.createElement('p');
      row.textContent = '商品 ' + (i + 1);
      return row;
    }));
    output.textContent = box.clientWidth + 'px / 溢出:' +
      (box.scrollHeight > box.clientHeight);
  }
  document.querySelector('button').onclick = () => {
    count = count === 2 ? 20 : 2;
    render();
  };
  render();
</script>

在傳統捲軸環境,auto 的長清單通常比短清單窄,stable 則讓兩者的 clientWidth 一致。若兩種設定都量到相同寬度,看看瀏覽器是否使用覆蓋式捲軸。它浮在內容上方,本來就不占版面,stable 也不會另外留白。實際像素會隨系統及瀏覽器而變。

整頁位移與左右對齊怎麼處理

若是整頁內容忽長忽短,且捲動發生在瀏覽器視窗,將 scrollbar-gutter: stable 設在 html。根元素的設定會套用到視窗,寫在 body 則不會以同樣方式傳遞。局部面板仍應把設定留在面板本身。

如果右側預留的空間讓置中內容看起來偏左,可以試 stable both-edges。只要一側本來就有捲軸預留區,另一側也會補一條等寬的空間。窄面板會因此少一點可用寬度,先用長商品名稱和最窄的支援寬度確認換行。

舊瀏覽器若不認得這個屬性,會保留原本的 overflow-y: auto 行為。若捲軸出現前後量到的內容寬度沒變,卻仍有位移,可以再看圖片是否先保留尺寸,或清單上方是否插入提示列。

封面為 AI 生成的概念插畫。

參考資料

原文鏈接:https://wntheme.com/css-scrollbar-gutter-stable/,轉載請註明出處。
0
顯示驗證碼
沒有帳號?註冊  忘記密碼?