StackOverflow上有几个关于offsetWidth / clientWidth / scrollWidth(和-Height)的问题,但没有一个问题可以全面解释这些值是什么。
此外,网上有几个消息来源提供令人困惑或不正确的信息。
您能否给出完整的解释,包括一些视觉提示? 另外,如何使用这些值来计算滚动条宽度?
答案 0 :(得分:764)
CSS框模型相当复杂,特别是在滚动内容时。虽然浏览器使用CSS中的值来绘制框,但如果只有CSS,则使用JS确定所有维度并不是直截了当的。
这就是为什么每个元素都有六个DOM属性以方便您使用:offsetWidth
,offsetHeight
,clientWidth
,clientHeight
,scrollWidth
和scrollHeight
。这些是表示当前可视布局的只读属性,所有这些属性都是整数(因此可能会出现舍入错误)。
让我们详细介绍一下:
offsetWidth
,offsetHeight
:包含所有边框的视觉框的大小。可以通过添加width
/ height
以及填充和边框来计算,如果元素具有display: block
clientWidth
,clientHeight
:框内容的可视部分,不包括边框或滚动条,但包括填充。无法直接从CSS计算,取决于系统的滚动条大小。scrollWidth
,scrollHeight
:所有框内容的大小,包括当前隐藏在滚动区域外的部分。无法直接从CSS计算,取决于内容。由于offsetWidth
考虑了滚动条宽度,我们可以使用它通过公式计算滚动条宽度
scrollbarWidth = offsetWidth - clientWidth - getComputedStyle().borderLeftWidth - getComputedStyle().borderRightWidth
不幸的是,我们可能会出现四舍五入的错误,因为offsetWidth
和clientWidth
总是整数,而实际尺寸可能是小于1而不是1的缩放级别。
注意这个
scrollbarWidth = getComputedStyle().width + getComputedStyle().paddingLeft + getComputedStyle().paddingRight - clientWidth
不在Chrome中可靠地运行,因为Chrome返回width
且滚动条已经减去。 (另外,Chrome会将paddingBottom渲染到滚动内容的底部,而其他浏览器则不会)
答案 1 :(得分:37)
我创建了一个更全面,更清晰的版本,有些人可能会发现这对于记住哪个名称对应哪个值很有用。我使用了Chrome Dev Tool的颜色代码,并且对称地组织标签以更快地获取类比:
注1:clientLeft
还包括垂直滚动的宽度
如果文本的方向设置为从右到左(因为
在这种情况下,栏显示在左侧)
注意2:最外面的一行代表最近的 定位 父级
(position
属性设置为不同于的值的元素
static
或initial
)。因此,如果直接容器不是 定位
element,那么该行不代表第一个容器
层次结构,但层次结构中更高的另一个元素。如果不
找到 定位 父级,浏览器将选择html
或body
元素作为参考
希望有人觉得它很有用,只需要我2美分;)
答案 2 :(得分:30)
如果你想使用scrollWidth来获得" REAL" 内容宽度/高度(因为内容可能比css定义的宽度更大) / height-Box) scrollWidth / Height非常难以置信,因为某些浏览器似乎" MOVE" paddingRIGHT& paddingBOTTOM如果内容很大。然后他们将衬垫放在"太宽/高内容"的右/底部。 (见下图)。
==> 因此,要在某些浏览器中获取REAL CONTENT WIDTH,您必须从滚动宽度中减去BOTH填充,在某些浏览器中,您只需要减去LEFT Padding。
我找到了一个解决方案,并希望将其添加为评论,但不允许。所以我拍摄了这张照片,并且在移动填充物方面使它更加清晰"和#34;不可靠的scrollWidth"。 在BLUE AREA,您可以找到解决方案,了解如何获得" REAL"内容宽度!
希望这有助于使事情变得更加清晰!
答案 3 :(得分:12)
有一篇关于MDN的好文章解释了这些概念背后的理论: https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/Determining_the_dimensions_of_elements
它还解释了boundingClientRect的宽度/高度与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中的15px,ff49和safari9中的15px,以及ie11中的17px(通过截屏中的photoshop测量完成,并通过测试结果证明)。
但是,在某些情况下,您的应用可能没有使用默认的垂直滚动条的宽度。
因此,给定这些概念的定义,垂直滚动条的宽度应等于(伪代码):
布局尺寸:offsetWidth - clientWidth - (borderLeftWidth + borderRightWidth)
渲染维度:boundingClientRect.width - clientWidth - (borderLeftWidth + borderRightWidth)
注意,如果您不了解布局与渲染,请阅读mdn文章。
此外,如果您有其他浏览器(或者您想亲自查看测试结果),可以在此处查看我的测试页:http://codepen.io/lingtalfi/pen/BLdBdL
答案 4 :(得分:3)
我的个人备忘单,内容包括:
.offsetWidth
/ .offsetHeight
.clientWidth
/ .clientHeight
.scrollWidth
/ .scrollHeight
.scrollLeft
/ .scrollTop
.getBoundingClientRect()
具有小/简单/非一体的图表:)
?查看原尺寸:https://docs.google.com/drawings/d/1bOOJnkN5G_lBs3Oz9NfQQH1I0aCrX5EZYPY3mu3_ROI/edit?usp=sharing