Html CSS:如何获取浏览器滚动条宽度?(对于 :hover {overflow: auto} 不错的边距)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28360978/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 03:28:26  来源:igfitidea点击:

CSS: How to get browser scrollbar width? (for :hover {overflow: auto} nice margins)

htmlcsswidthscrollbar

提问by Jacek Kowalewski

I'm not sure if title is clear, so few words of explanation. I've got few little elements, let say div's (200pxx 400pxCONSTANT). Inside each of them, there is a paragraph with about 20 lines of text. Of course, this it to much for a poor little div. What I want to do is:

我不确定标题是否清楚,所以解释的话很少。我有几个小元素,比如说div( 200pxx 400pxCONSTANT)。在它们每个内部,都有一个包含大约 20 行文本的段落。当然,这对于一个可怜的小 div 来说太过分了。我想做的是:

  1. Normally divhas overflow: hiddenproperty.
  2. On mouse over (:hover) this property is changed to overflow: auto;, and the scrollbar appears.
  1. 通常divoverflow: hidden属性。
  2. 鼠标悬停在 ( :hover) 上时,此属性将更改为overflow: auto;,并出现滚动条。

What is the problem? I want a little space (padding or margin) between the paragraph text and the scrollbar. Let's say that paragraph has a symetrical margin: 20px;. But after :hovertriggers on, the scrollbar appears, and the whole right side of the paragraph is moved "scrollbar-width" pxto the left. Sentences are broken in other lines, and the whole paragraph look different, which is quite annoying and not user friendly. How can I set my CSS, so the only change after hover will be the appearance of scroolbar?

问题是什么?我想要段落文本和滚动条之间的一点空间(填充或边距)。假设该段落有一个对称的margin: 20px;. 但:hover触发后,滚动条出现,整个段落"scrollbar-width" px的右侧向左移动。其他几行断句,整段看起来都不一样,很烦人,不友好。如何设置我的 CSS,因此悬停后唯一的变化将是滚动条的外观?

In other words:

换句话说:

/* Normally no scrollbar */
div {display: block; width: 400px; height: 200px; overflow: hidden;}
/* On hover scrollbar appears */
div:hover {overflow: auto;}

/* Paragraph margin predicted for future scrollbar on div */
div p {margin: 20px (20px + scrollbarwidth px) 20px 50px;}
/* With scrollbar margin is symmetrical */
div:hover p {margin: 20px;} /* With scrollbar */

I have done a little snippet for it, with exaplanation of my problem in strong. I hope everything is clear :).I'm searching for a solution for almost two hours now, so I think my question is quite unique and interesting.

我已经为它做了一个小片段,并在strong. 我希望一切都清楚:)。我现在正在寻找解决方案将近两个小时,所以我认为我的问题非常独特和有趣。

div.demo1 {
  width: 400px;
  height: 200px;
  overflow: hidden;
  background: #ddd;
}
div.demo1:hover {
  overflow: auto;
}
div.demo1 p {
  background: #eee;
  margin: 20px;
}
div.demo2 {
  width: 400px;
  height: 200px;
  overflow: hidden;
  background: #ddd;
}
div.demo2:hover {
  overflow: auto;
}
div.demo2 p {
  background: #eee;
  margin: 20px 40px 20px 20px;
}
div.demo2:hover p {
  margin: 20px 20px 20px 20px;
}
<div class="demo1">
  <p>
    This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text.
    This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text.
    This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text.
    This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text.
    This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text.
  </p>
</div>
<br>
<br>
<strong>As you can see, on hover right side of the paragraph "moves" left. But I want something like:</strong>
<br>
<br>
<div class="demo2">
  <p>
    This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text.
    This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text.
    This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text.
    This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text.
    This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text.
  </p>
</div>

<strong>But with a "perfect" scrollbar width (in this example I used 20px)</strong>

回答by tomtomtom

All scrollbar can be different according to browser and OS so you must use javascript.

所有滚动条可能因浏览器和操作系统而异,因此您必须使用 javascript。

I found a cool snippet here : http://davidwalsh.name/detect-scrollbar-width

我在这里找到了一个很酷的片段:http: //davidwalsh.name/detect-scrollbar-width

And that an exemple : http://jsfiddle.net/a1m6an3u/

这是一个例子:http: //jsfiddle.net/a1m6an3u/

The js code create a div .scrollbar-measure, look the size of the scrollbar and return it.

js 代码创建一个 div .scrollbar-measure,查看滚动条的大小并返回它。

It look like this :

它看起来像这样:

var scrollDiv = document.createElement("div");
scrollDiv.className = "scrollbar-measure";
document.body.appendChild(scrollDiv);

// Get the scrollbar width
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
console.warn(scrollbarWidth); // Mac:  15

// Delete the DIV 
document.body.removeChild(scrollDiv);

So I quickly added some jquery code but I think you can do it in only JS.

所以我很快添加了一些 jquery 代码,但我认为你只能在 JS 中完成。

回答by Oliver

Whilst tomtomtom's answer works fantastically, it requires an external CSS snippet that seems somewhat unnecessary, and Yurii's answer requires jQuery, which again seems sorta overkill for this. A slightly more up-to-date and self-contained answer (which can also be used in a JavaScript module setup) is:

虽然 tomtomtom 的答案非常有效,但它需要一个似乎有些不必要的外部 CSS 片段,而 Yurii 的答案需要 jQuery,这再次似乎有点矫枉过正。稍微更新和自包含的答案(也可以在 JavaScript 模块设置中使用)是:

class TempScrollBox {
  constructor() {
    this.scrollBarWidth = 0;

    this.measureScrollbarWidth();
  }

  measureScrollbarWidth() {
    // Add temporary box to wrapper
    let scrollbox = document.createElement('div');

    // Make box scrollable
    scrollbox.style.overflow = 'scroll';

    // Append box to document
    document.body.appendChild(scrollbox);

    // Measure inner width of box
    this.scrollBarWidth = scrollbox.offsetWidth - scrollbox.clientWidth;

    // Remove box
    document.body.removeChild(scrollbox);
  }

  get width() {
    return this.scrollBarWidth;
  }
}

This class can then be used like so:

然后可以像这样使用这个类:

let scrollbox = new TempScrollBox();

console.log(scrollbox.width) //-> 17 (Windows, Chrome)

Fiddle: https://jsfiddle.net/nu9oy1bc/

小提琴:https: //jsfiddle.net/nu9oy1bc/

回答by Yurii Semeniuk

If someone, like me, found this question by googling "how to get browser scrollbar width", here is jQuery implementation without any additional CSS classes:

如果有人像我一样通过谷歌搜索“如何获取浏览器滚动条宽度”发现了这个问题,这里是没有任何额外 CSS 类的 jQuery 实现:

var div = $("<div style='overflow:scroll;position:absolute;top:-99999px'></div>").appendTo("body"),
    width = div.prop("offsetWidth") - div.prop("clientWidth");
div.remove();

console.log(width);

or JSFiddle, if you like.

或者JSFiddle,如果你喜欢。

Thanks tomtomtom's answerfor the idea

感谢tomtomtom对这个想法的回答

回答by Roland Pihlakas

Pure CSS solution here.
I would create an invisible div on the right of your text div with forced scrollbar inside it:

纯 CSS 解决方案在这里。
我会在文本 div 的右侧创建一个不可见的 div,里面有强制滚动条:

<div class="container">
  <div class="text">Your very and very long text here</div>
  <div class="scrollbar-width"></div>
</div>
<style>
.container {
   display: flex;
   width: 100px; /* to make scrollbar necessary */
   height: 30px; /* to make scrollbar necessary */
   border: 1px solid blue;
}
.text {
   flex: 1; 
   float: left;
   overflow-y: hidden; 
}
.scrollbar-width {
   float: left; 
   overflow-x: hidden; 
   overflow-y: scroll; 
   visibility: hidden;
}
.scrollbar-width::-webkit-scrollbar { /* for debugging */
  background-color: red;
}
.text:hover {
   overflow-y: scroll; 
}
.text:hover + .scrollbar-width {
  display: none;
}
</style>

When the scrollbar-widthdiv is marked with visibility: hiddenit will still take space.

scrollbar-widthdiv 被标记时,visibility: hidden它仍然会占用空间。

Now when you finally decide to show your own scrollbar, add display: noneto the invisible scrollbar-widthdiv, so it does not take space anymore, and therefore your textdiv fills all available space and becomes wider.

现在,当您最终决定显示自己的滚动条时,将其添加display: none到不可见的scrollbar-widthdiv,这样它就不再占用空间,因此您的textdiv 会填满所有可用空间并变得更宽。

In case you wish to verify, remove visibility: hidden;from the style of scrollbar-widthdiv. Then you can see how this placeholder div is initially taking space (it appears red according to the "for debugging" style above) and on hover it disappears and is replaced by the text div-s scrollbar.

如果您想验证,请visibility: hidden;scrollbar-widthdiv样式中删除。然后你可以看到这个占位符 div 最初是如何占用空间的(根据上面的“用于调试”样式,它显示为红色)并且在悬停时它消失并被文本 div-s 滚动条替换。

JS fiddle link: https://jsfiddle.net/rb1o0tkn/

JS小提琴链接:https: //jsfiddle.net/rb1o0tkn/

回答by gummiost

innerWidthreturns the width of the browser viewport including the scrollbar.

innerWidth返回浏览器视口的宽度,包括滚动条。

The read-only Window property innerWidth returns the interior width of the window in pixels. This includes the width of the vertical scroll bar, if one is present.

只读 Window 属性 innerWidth 返回窗口的内部宽度(以像素为单位)。这包括垂直滚动条的宽度(如果存在)。

clientWidthreturns the width of viewport, excluding the scrollbar, when used on a root element like document.

clientWidth在用于根元素(如document )时返回视口的宽度,不包括滚动条。

When clientWidth is used on the root element (the element), (or on if the document is in quirks mode), the viewport's width (excluding any scrollbar) is returned.

当在根元素(元素)上使用 clientWidth 时(如果文档处于怪癖模式,则为 on),将返回视口的宽度(不包括任何滚动条)。

let scrollbarWidth = (window.innerWidth - document.body.clientWidth) + 'px';

Subtract the two values and voila, you get the width of the scrollbar.

减去这两个值,瞧,你得到滚动条的宽度。

This example would usually return: 15px

这个例子通常会返回:15px