Understanding offsetWidth, clientWidth, scrollWidth and -Height, respectively
在StackOverflow上有几个关于offsetWidth / clientWidth / scrollWidth(分别是-Height和)的问题,但是没有一个问题可以全面解释这些值是什么。
另外,网络上有多个来源提供令人困惑或不正确的信息。
您能否给出完整的解释,包括一些视觉提示?
另外,这些值如何用于计算滚动条宽度?
CSS盒子模型相当复杂,尤其是在滚动内容时。虽然浏览器使用CSS中的值来绘制框,但是如果您只有CSS,则使用JS确定所有尺寸并不是直截了当的。
因此,为方便起见,每个元素都有六个DOM属性:
让我们详细了解一下它们:
-
offsetWidth ,offsetHeight :包括所有边框的可视框的大小。如果元素具有display: block ,则可以通过添加width /height 以及填充和边框来计算 -
clientWidth ,clientHeight :框内容的可视部分,不包括边框或滚动条,但包括padding。无法直接从CSS计算,取决于系统的滚动条大小。 -
scrollWidth ,scrollHeight :该框所有内容的大小,包括当前隐藏在滚动区域之外的部分。不能直接从CSS计算,取决于内容。
试试看:jsFiddle
由于
1 | scrollbarWidth = offsetWidth - clientWidth - getComputedStyle().borderLeftWidth - getComputedStyle().borderRightWidth |
不幸的是,由于
注意这个
1 | scrollbarWidth = getComputedStyle().width + getComputedStyle().paddingLeft + getComputedStyle().paddingRight - clientWidth |
在Chrome中无法可靠地运行,因为Chrome返回的
我创建了一个更全面,更简洁的版本,有些人可能会觉得对记住哪个名称对应哪个值很有用。我使用Chrome Dev Tool的颜色代码和标签进行了对称组织,以更快地获得类比:
-
注1:
clientLeft 还包括垂直滚动的宽度
如果文本方向设置为从右到左(因为
在这种情况下,栏会显示在左侧) -
注2:最外面的线表示最接近的父级
(其position 属性设置为与
static 或initial )。因此,如果直接容器不在
元素,则该行不代表中的第一个容器
层次结构中的另一个元素。如果不
找到定位的父对象,浏览器将使用html 或body
元素作为参考
希望有人发现它有用,只有我的2美分;)
如果您要使用scrollWidth来获取" REAL"内容的宽度/高度(因为内容可能比css定义的width / height-Box大),scrollWidth / Height是非常不可靠的,因为某些浏览器似乎在"移动" paddingRIGHT &paddingBOTTOM(如果内容太大)。然后,他们将填充物放在"太宽/太高的内容"的右/底部(请参见下图)。
==>因此,要在某些浏览器中获得真实内容宽度,您必须从scrollwidth中减去两个填充,而在某些浏览器中,您仅需减去LEFT Padding。
我为此找到了解决方案,并希望将其添加为评论,但不允许这样做。所以我拍了张照片,使它的"移动的填充"和"不可靠的scrollWidth"更加清晰了。在蓝色区域中,您可以找到有关如何获得"真实"内容宽度的解决方案!
希望这有助于使事情变得更加清晰!
关于MDN的一篇很好的文章解释了这些概念背后的理论:
https://developer.mozilla.org/zh-CN/docs/Web/API/CSS_Object_Model/Det??ermining_the_dimensions_of_elements
好。
它还说明了boundingClientRect的width / height与offsetWidth / offsetHeight之间的重要概念差异。
好。
然后,要证明该理论是对还是错,您需要进行一些测试。
那就是我在这里所做的:https://github.com/lingtalfi/dimensions-cheatsheet
好。
它正在测试chrome53,ff49,safari9,edge13和ie11。
好。
测试结果证明该理论大体正确。
对于测试,我创建了3个div,每个div包含10个lorem ipsum段落。
一些CSS应用于它们:
好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | .div1{ width: 500px; height: 300px; padding: 10px; border: 5px solid black; overflow: auto; } .div2{ width: 500px; height: 300px; padding: 10px; border: 5px solid black; box-sizing: border-box; overflow: auto; } .div3{ width: 500px; height: 300px; padding: 10px; border: 5px solid black; overflow: auto; transform: scale(0.5); } |
结果如下:
好。
div1
好。
bcr.height:330(chrome53,ff49,safari9,edge13,ie11)
好。
clientWidth:505(chrome53,ff49,safari9)
好。
clientHeight:320(chrome53,ff49,safari9,edge13,ie11)
好。
scrollWidth:505(chrome53,safari9,ff49)
好。
好。
div2
好。
clientHeight:290(chrome53,ff49,safari9,edge13,ie11)
好。
scrollWidth:475(chrome53,safari9,ff49)
好。
好。
div3
好。
clientHeight:320(chrome53,ff49,safari9,edge13,ie11)
好。
scrollWidth:505(chrome53,safari9,ff49)
好。
好。
好。
因此,除了edge13和ie11中boundingClientRect的高度值(299.9999694824219,而不是预期的300)之外,结果证实了此背后的理论是可行的。
好。
从那里开始,这是我对这些概念的定义:
好。
好。
注意:默认的垂直滚动条的宽度在edge13中为12px,在chrome53,ff49和safari9中为15px,在ie11中为17px(通过在photoshop中通过屏幕截图进行测量,并由测试结果证明正确)。
好。
但是,在某些情况下,您的应用可能未使用默认的垂直滚动条的宽度。
好。
因此,给定这些概念的定义,垂直滚动条的宽度应等于(用伪代码):
好。
布局尺寸:offsetWidth-clientWidth-(borderLeftWidth + borderRightWidth)
好。
呈现尺寸:boundingClientRect.width-clientWidth-(borderLeftWidth + borderRightWidth)
好。
好。
请注意,如果您不了解布局与渲染,请阅读mdn文章。
好。
另外,如果您使用其他浏览器(或者希望自己查看测试结果),则可以在此处查看我的测试页:http://codepen.io/lingtalfi/pen/BLdBdL
好。
好。