在StackOverflow上有几个关于offsetWidth / clientWidth / scrollWidth(和-Height分别)的问题,但是没有一个问题可以全面解释这些值是什么。
另外,网络上有多个来源提供令人困惑或不正确的信息。
您能否给出完整的解释,包括一些视觉提示?另外,这些值如何用于计算滚动条宽度?
在StackOverflow上有几个关于offsetWidth / clientWidth / scrollWidth(和-Height分别)的问题,但是没有一个问题可以全面解释这些值是什么。
另外,网络上有多个来源提供令人困惑或不正确的信息。
您能否给出完整的解释,包括一些视觉提示?另外,这些值如何用于计算滚动条宽度?
Answers:
CSS盒子模型相当复杂,尤其是在滚动内容时。尽管浏览器使用CSS中的值来绘制框,但是如果您只有CSS,则使用JS确定所有尺寸并不是直截了当的。
这就是为什么每个元素都为您提供方便6个DOM属性:offsetWidth
,offsetHeight
,clientWidth
,clientHeight
,scrollWidth
和scrollHeight
。这些是代表当前视觉布局的只读属性,并且它们都是整数(因此可能会舍入错误)。
让我们详细了解一下它们:
offsetWidth
,offsetHeight
:包括所有边框的可视框的大小。可以通过添加width
/ height
以及填充和边框(如果元素具有display: block
clientWidth
,clientHeight
:框内容的可视部分,不包括边框或滚动条,但包括padding。不能直接从CSS计算,取决于系统的滚动条大小。scrollWidth
,scrollHeight
:框的所有内容的大小,包括当前隐藏在滚动区域之外的部分。不能直接从CSS计算,取决于内容。由于offsetWidth
考虑了滚动条的宽度,因此我们可以通过公式使用它来计算滚动条的宽度
scrollbarWidth = offsetWidth - clientWidth - getComputedStyle().borderLeftWidth - getComputedStyle().borderRightWidth
不幸的是,由于offsetWidth
和clientWidth
始终是整数,因此我们可能会舍入错误,而实际大小可能是除1以外的缩放级别的分数。
请注意
scrollbarWidth = getComputedStyle().width + getComputedStyle().paddingLeft + getComputedStyle().paddingRight - clientWidth
在Chrome浏览器中无法正常运行,因为Chrome浏览器返回width
时已扣除滚动条。(此外,Chrome会将paddingBottom渲染到滚动内容的底部,而其他浏览器则不这样做)
naturalWidth
和naturalHeight
scrollHeight
包括padding-bottom
但scrollWidth
不包括padding-right
clientWidth
对于document.documentElement.clientWidth
是不同的,因为它似乎包括padding
,borders
和margin
我创建了一个更全面,更简洁的版本,有些人可能会觉得对记住哪个名称对应哪个值很有用。我使用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/en-US/docs/Web/API/CSS_Object_Model/Determining_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应用于它们:
.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
element.getBoundingClientRect()
(请参阅developer.mozilla.org/en-US/docs/Web/API/Element.clientWidth上的说明)