修復一個由於 scrollbar 佔據空間致使的 bug

背景

這一個由於滾動條佔據空間引發的bug, 查了一下資料, 最後也解決了,順便研究一下這個屬性, 作一下總結,分享給你們看看。css

正文

昨天, 測試提了個問題, 現象是一個輸入框的聚焦提示偏了, 讓我修一下, 以下圖:html

image.png

起初認爲是紅框提示位置不對, 就去找代碼看:git

<Input
  // ...
  onFocus={() => setFocusedInputName('guidePrice')}
  onBlur={() => setFocusedInputName('')}
/>

<Table
  data-focused-column={focusedInputName}
  // ...
/>

代碼上沒有什麼問題, 不是手動設置的,並且, 在我和另外一個同事, 還有PM的PC上都是OK的:github

image.png

初步判斷是,紅框位置結算有差別, 差別大小大概是17px, 可是這個差別是怎麼產生的呢?瀏覽器

就去測試小哥的PC上看, 注意到一個細節, 在我PC上, 滾動條是懸浮的: image.pngapp

在他PC上, 滾動條是佔空間的:ide

image.png

在他電腦上, 手動把本來的 overscroll-y: scroll 改爲 overscroll-y: overlay 問題就結局了。測試

由此斷定是: 滾動條佔據空間 引發的bug。ui

overscroll-y: overlay

CSS屬性 overflow, 定義當一個元素的內容太大而沒法適應塊級格式化上下文的時候該作什麼。它是 overflow-x 和overflow-y的 簡寫屬性 。
/* 默認值。內容不會被修剪,會呈如今元素框以外 */
overflow: visible;

/* 內容會被修剪,而且其他內容不可見 */
overflow: hidden;

/* 內容會被修剪,瀏覽器會顯示滾動條以便查看其他內容 */
overflow: scroll;

/* 由瀏覽器定奪,若是內容被修剪,就會顯示滾動條 */
overflow: auto;

/* 規定從父元素繼承overflow屬性的值 */
overflow: inherit;

官方描述:

overlay  行爲與 auto 相同,但滾動條繪製在內容之上而不是佔用空間。 僅在基於 WebKit(例如, Safari)和基於Blink的(例如, ChromeOpera)瀏覽器中受支持。

表現:

html {
  overflow-y: overlay;
}

兼容性

沒有在caniuse上找到這個屬性的兼容性, 也有人提這個問題:spa

image.png

問題場景以及解決辦法

1. 外部容器的滾動條

這裏的外部容器指的是html, 直接加在最外層:

html {
  overflow-y: scroll;
}

手動加上這個特性, 不論何時都有滾動寬度佔據空間。

缺點: 沒有滾動的時候也會有個滾動條, 不太美觀。

優勢: 方便, 沒有兼容性的問題。

2. 外部容器絕對定位法

用絕對定位,保證了body的寬度一直保持完整空間:

html {
  overflow-y: scroll; // 兼容ie8,不支持:root, vw
}

:root {
  overflow-y: auto;
  overflow-x: hidden;
}

:root body {
  position: absolute;
}

body {
  width: 100vw;
  overflow: hidden;
}

3. 內部容器作兼容

.wrapper {
    overflow-y: scroll; // fallback
    overflow-y: overlay;
}

總結

我的推薦仍是用 overlay, 而後使用scroll 作爲兜底。

內容就這麼多, 但願對你們有所啓發。

文章若有錯誤, 請在留言區指正, 謝謝。

參考資料

  1. https://developer.mozilla.org...
  2. https://github.com/Fyrd/caniu...
相關文章
相關標籤/搜索