分别了解offsetWidth,clientWidth,scrollWidth和-Height

use*_*621 355 html css dom

StackOverflow上有几个关于offsetWidth/clientWidth/scrollWidth(和-Height)的问题,但没有一个问题可以全面解释这些值是什么.

此外,网上有几个来源,提供令人困惑或不正确的信息.

你能给出一个完整的解释,包括一些视觉提示吗?另外,如何使用这些值来计算滚动条宽度?

use*_*621 814

CSS框模型相当复杂,特别是在滚动内容时.虽然浏览器使用CSS中的值来绘制框,但如果只有CSS,则使用JS确定所有维度并不是直截了当的.

这就是为什么每个元素都为您提供方便6个DOM属性:offsetWidth,offsetHeight,clientWidth,clientHeight,scrollWidthscrollHeight.这些是表示当前可视布局的只读属性,并且它们都是整数(因此可能会出现舍入错误).

让我们详细介绍一下:

  • offsetWidth,offsetHeight:视觉框的大小包含所有边界.如果元素有,可以通过添加width/ height和填充和边框来计算display: block
  • clientWidth,clientHeight:框内容的可视部分,不包括边框或滚动条,但包括填充.无法直接从CSS计算,取决于系统的滚动条大小.
  • scrollWidth,scrollHeight:所有盒子内容的大小,包括当前隐藏在滚动区域之外的部分.无法直接从CSS计算,取决于内容.

CSS2 Box模型

尝试一下:jsFiddle


由于offsetWidth考虑了滚动条宽度,我们可以使用它通过公式计算滚动条宽度

scrollbarWidth = offsetWidth - clientWidth - getComputedStyle().borderLeftWidth - getComputedStyle().borderRightWidth
Run Code Online (Sandbox Code Playgroud)

不幸的是,我们可能会得到四舍五入的错误,因为offsetWidth并且clientWidth总是整数,而实际大小可能是小于1而不是1的缩放级别.

请注意这一点

scrollbarWidth = getComputedStyle().width + getComputedStyle().paddingLeft + getComputedStyle().paddingRight - clientWidth
Run Code Online (Sandbox Code Playgroud)

在Chrome 中无法正常运行,因为Chrome返回width的滚动条已经减去.(另外,Chrome将paddingBottom渲染到滚动内容的底部,而其他浏览器则不会)

  • 对于那些寻求比整数更精细的粒度的人,使用`element.getBoundingClientRect()`(参见https://developer.mozilla.org/en-US/docs/Web/API/Element.clientWidth上的注释) (27认同)
  • 请注意,根据您的布局,scrollWidth 和scrollHeight 对于获取伪元素::before 和::after 的大小非常有用。 (2认同)
  • 为什么 `scrollHeight` 包含 `padding-bottom` 但 `scrollWidth` 不包含 `padding-right` (2认同)
  • “document.documentElement.clientWidth”的“clientWidth”是不同的,因为它似乎包括“padding”、“borders”和“margin” (2认同)
  • 根据 clientWidth 规范,如果元素是 `HTML` 或 `body` 元素,“返回视口宽度,不包括渲染的滚动条的大小(如果有)。”,因此 `document.documentElement.clientWidth` 包括 padding/边框/边距 https://www.w3.org/TR/cssom-view/#dom-element-clientwidth (2认同)

Lua*_*ual 43

我创建了一个更全面,更清晰的版本,有些人可能会发现这对于记住哪个名称对应哪个值很有用.我使用了Chrome Dev Tool的颜色代码,并且对称地组织标签以更快地获取类比:

在此输入图像描述

  • 注1:clientLeft如果文本的方向设置为从右到左,则还包括垂直滚动条的宽度(因为在这种情况下条形图显示在左侧)

  • 注2:最外层线表示最接近的定位的父(一个元件,其position属性被设定为比不同的值 staticinitial).因此,如果直接容器不是定位 元素,则该行不表示层次结构中的第一个容器,而是层次结构中较高的另一个元素.如果未 找到定位的父级,则浏览器将使用htmlor body 元素作为引用


希望有人发现它有用,只需我2美分;)

  • 我不确定这是否正确......如果没有彩色区域的标签,很难判断。您似乎在说 clientWidth 不包括填充...这是错误的 (2认同)

Man*_*459 30

如果你想使用scrollWidth来获得"REAL" 内容宽度/高度(因为内容可能比css定义的宽度/高度框更大),scrollWidth/Height非常不可靠,因为某些浏览器似乎"移动"了paddingRIGHT &paddingBOTTOM如果内容很大.然后他们将填充物置于"太宽/高含量"的右/底部(见下图).

==>因此,要在某些浏览器中获得REAL CONTENT WIDTH,您必须从滚动宽度中减去BOTH填充,在某些浏览器中,您只需要减去LEFT Padding.

我找到了一个解决方案,并希望将其添加为注释,但不允许.所以我拍摄了这张照片,并且在"移动的填充"和"不可靠的scrollWidth"方面使它更加清晰.在蓝色区域,你找到了我的解决方案,如何获得"真正的"内容宽度!

希望这有助于使事情更清晰!

在此输入图像描述


lin*_*ing 13

有一篇关于MDN的好文章解释了这些概念背后的理论:https: //developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/Det​​ermining_the_dimensions_of_elements

它还解释了boundingClientRect的宽度/高度与offsetWidth/offsetHeight之间的重要概念差异.

然后,为了证明理论是对还是错,你需要进行一些测试.这就是我在这里所做的:https://github.com/lingtalfi/dimensions-cheatsheet

它正在测试chrome53,ff49,safari9,edge13和ie11.

测试结果证明该理论通常是正确的.对于测试,我创建了3个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);
}
Run Code Online (Sandbox Code Playgroud)

以下是结果:

  • DIV1

    • offsetWidth:530(chrome53,ff49,safari9,edge13,ie11)
    • offsetHeight:330(chrome53,ff49,safari9,edge13,ie11)
    • bcr.width:530(chrome53,ff49,safari9,edge13,ie11)
    • bcr.height:330(chrome53,ff49,safari9,edge13,ie11)

    • clientWidth:505(chrome53,ff49,safari9)

    • clientWidth:508(edge13)
    • clientWidth:503(ie11)
    • clientHeight:320(chrome53,ff49,safari9,edge13,ie11)

    • scrollWidth:505(chrome53,safari9,ff49)

    • scrollWidth:508(edge13)
    • scrollWidth:503(ie11)
    • scrollHeight:916(chrome53,safari9)
    • scrollHeight:954(ff49)
    • scrollHeight:922(edge13,ie11)
  • DIV2

    • offsetWidth:500(chrome53,ff49,safari9,edge13,ie11)
    • offsetHeight:300(chrome53,ff49,safari9,edge13,ie11)
    • bcr.width:500(chrome53,ff49,safari9,edge13,ie11)
    • bcr.height:300(chrome53,ff49,safari9)
    • bcr.height:299.9999694824219(edge13,ie11)
    • clientWidth:475(chrome53,ff49,safari9)
    • clientWidth:478(edge13)
    • clientWidth:473(ie11)
    • clientHeight:290(chrome53,ff49,safari9,edge13,ie11)

    • scrollWidth:475(chrome53,safari9,ff49)

    • scrollWidth:478(edge13)
    • scrollWidth:473(ie11)
    • scrollHeight:916(chrome53,safari9)
    • scrollHeight:954(ff49)
    • scrollHeight:922(edge13,ie11)
  • DIV3

    • offsetWidth:530(chrome53,ff49,safari9,edge13,ie11)
    • offsetHeight:330(chrome53,ff49,safari9,edge13,ie11)
    • bcr.width:265(chrome53,ff49,safari9,edge13,ie11)
    • bcr.height:165(chrome53,ff49,safari9,edge13,ie11)
    • clientWidth:505(chrome53,ff49,safari9)
    • clientWidth:508(edge13)
    • clientWidth:503(ie11)
    • clientHeight:320(chrome53,ff49,safari9,edge13,ie11)

    • scrollWidth:505(chrome53,safari9,ff49)

    • scrollWidth:508(edge13)
    • scrollWidth:503(ie11)
    • scrollHeight:916(chrome53,safari9)
    • scrollHeight:954(ff49)
    • scrollHeight:922(edge13,ie11)

因此,除了edge13和ie11中的boundingClientRect的高度值(299.9999694824219而不是预期的300)之外,结果证实了这背后的理论有效.

从那里,我是这些概念的定义:

  • offsetWidth/offsetHeight:布局边框的尺寸
  • boundingClientRect:渲染边框的尺寸
  • clientWidth/clientHeight:布局填充框的可见部分的尺寸(不包括滚动条)
  • scrollWidth/scrollHeight:布局填充框的尺寸,如果它不受滚动条约束

注意:默认垂直滚动条的宽度为edge13中的12px,chrome53中的15px,ff49和safari9中的15px,以及ie11中的17px(通过截屏中的photoshop中的测量完成,并且通过测试结果证明是正确的).

但是,在某些情况下,您的应用可能没有使用默认的垂直滚动条的宽度.

因此,给定这些概念的定义,垂直滚动条的宽度应等于(伪代码):

  • layout dimension:offsetWidth - clientWidth - (borderLeftWidth + borderRightWidth)

  • 渲染维度:boundingClientRect.width - clientWidth - (borderLeftWidth + borderRightWidth)

注意,如果您不了解布局与渲染,请阅读mdn文章.

此外,如果您有其他浏览器(或者如果您想亲自查看测试结果),可以在此处查看我的测试页面:http://codepen.io/lingtalfi/pen/BLdBdL


abe*_*ier 9

我的个人备忘单,包括:

DOM 元素尺寸

  • .offsetWidth/.offsetHeight
  • .clientWidth/.clientHeight
  • .scrollWidth/.scrollHeight
  • .scrollLeft/.scrollTop
  • .getBoundingClientRect()

带有小/简单/非多合一图表:)


查看全尺寸:https : //docs.google.com/drawings/d/1bOOJnkN5G_lBs3Oz9NfQQH1I0aCrX5EZYPY3mu3_ROI/edit?usp=sharing