乐闻世界logo
搜索文章和话题

What is the different between offsetwidth clientwidth scrollwidth and height respectively

7 个月前提问
3 个月前修改
浏览次数47

6个答案

1
2
3
4
5
6

offsetWidthclientWidthscrollWidth 以及 height 是与 HTML 元素的大小和滚动相关的不同属性。下面我将详细解释它们之间的区别:

offsetWidth

  • 定义: offsetWidth 是元素的布局宽度,包括元素的可视宽度、边框(border)、内边距(padding),但不包括外边距(margin)。
  • 使用场景: 当你需要元素的整体宽度时,包括它的边框和内边距。
  • 例子: 如果一个元素的宽度为100px,左右内边距分别为10px,左右边框宽度分别为1px,那么offsetWidth将会是 100 + 10 + 10 + 1 + 1 = 122px。

clientWidth

  • 定义: clientWidth 是元素的内部可视宽度,包括内边距,但不包括边框和垂直滚动条(如果有的话),也不包括外边距。
  • 使用场景: 当你想要获取元素内容区域加上内边距的宽度,但不包括边框或滚动条。
  • 例子: 对于上面同一个元素,clientWidth 将会是 100 + 10 + 10 = 120px(假设没有垂直滚动条)。

scrollWidth

  • 定义: scrollWidth 是元素的完整内容宽度,包括因为溢出被隐藏的部分。它包括内边距,但不包括边框和垂直滚动条(如果有的话),也不包括外边距。
  • 使用场景: 当你需要获取元素内容实际占用的总宽度,包括看得见和看不见(溢出部分)的内容。
  • 例子: 如果上面的元素内有足够的内容使其出现水平滚动条,而内容的实际宽度为300px,那么scrollWidth将会是 300 + 10 + 10 = 320px。

height

  • 定义: height 不是一个标准的 DOM 属性,它通常指的是通过 CSS 设置的元素的高度(不包括内边距、边框或外边距)。
  • 使用场景: 当你需要定义或获取元素的内容区域的高度时。
  • 例子: 如果你通过 CSS 设置了height: 200px;,那么这个元素的内容区域高度就是200px,不考虑其他任何因素。

总结一下,offsetWidthclientWidth都是考虑元素在页面布局中占用的实际空间,而scrollWidth是元素内容的实际宽度,不管是否可见。另一方面,height通常是通过CSS设置的属性,指定了元素的内容区域的高度。这些属性都是针对元素宽度和高度的不同方面的计量。

2024年6月29日 12:07 回复

CSS 盒子模型相当复杂,尤其是在滚动内容时。虽然浏览器使用 CSS 中的值来绘制框,但如果您只有 CSS,则使用 JS 确定所有尺寸并不简单。

这就是为什么每个元素都有六个 DOM 属性以方便您使用:offsetWidthoffsetHeightclientWidthclientHeightscrollWidthscrollHeight这些是表示当前视觉布局的只读属性,并且它们都是_整数_(因此可能会出现舍入错误)。

让我们详细了解一下它们:

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

CSS2 盒子模型

尝试一下:jsFiddle


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

shell
scrollbarWidth = offsetWidth - clientWidth - getComputedStyle().borderLeftWidth - getComputedStyle().borderRightWidth

不幸的是,我们可能会遇到舍入误差,因为offsetWidthclientWidth始终是整数,而实际大小可能是缩放级别不是 1 的小数。

请注意,这

shell
scrollbarWidth = getComputedStyle().width + getComputedStyle().paddingLeft + getComputedStyle().paddingRight - clientWidth

在 Chrome 中无法可靠工作,因为 Chrome 返回时width滚动条已被减去。 (此外,Chrome 将 paddingBottom 渲染到滚动内容的底部,而其他浏览器则不会)

2024年6月29日 12:07 回复

我创建了一个更全面、更清晰的版本,有些人可能会发现它对于记住哪个名称对应哪个值很有用。我使用 Chrome 开发工具的颜色代码和对称组织的标签,以便更快地进行类比:

在此输入图像描述

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

  • 注 2:最外面的线代表最接近的定位position父元素(其属性设置为不同于 static或 的值的元素initial)。因此,如果直接容器不是定位 元素,则该行不代表层次结构中的第一个容器,而是代表层次结构中更高的另一个元素。如果没有 找到定位的html父元素,浏览器将采用orbody 元素作为参考


希望有人觉得它有用,只是我的 2 美分;)

2024年6月29日 12:07 回复

如果您想使用scrollWidth来获取**“真实”** 内容宽度/高度(因为内容可能比css定义的宽度/高度框更大),则scrollWidth /Height非常不可靠,因为某些浏览器似乎“移动”了paddingRIGHT & paddingBOTTOM 如果内容太大。然后,他们将填充物放置在“太宽/太高的内容”的右侧/底部(见下图)。

**==>**因此,要在某些浏览器中获得真实内容宽度,您必须从滚动宽度中减去两个填充,而在某些浏览器中,您只需减去左侧填充。

我找到了一个解决方案,并想将其添加为评论,但不允许。所以我拍了这张照片,并使其在“移动的填充”和“不可靠的滚动宽度”方面变得更加清晰。在蓝色区域中,您可以找到有关如何获得“真实”内容宽度的解决方案!

希望这有助于让事情变得更加清晰!

在此输入图像描述

2024年6月29日 12:07 回复

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,每个 div 包含 10 个 lorem ipsum 段落。一些 CSS 应用于它们:

shell
.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); }

结果如下:

  • 分区1

    • 偏移宽度:530(chrome53、ff49、safari9、edge13、ie11)

    • 偏移高度:330(chrome53、ff49、safari9、edge13、ie11)

    • bcr.宽度:530(chrome53、ff49、safari9、edge13、ie11)

    • bcr.高度:330(chrome53、ff49、safari9、edge13、ie11)

    • 客户端宽度:505(chrome53、ff49、safari9)

    • 客户端宽度:508(边缘13)

    • 客户端宽度:503(即11)

    • 客户端高度:320(chrome53、ff49、safari9、edge13、ie11)

    • 滚动宽度:505(chrome53、safari9、ff49)

    • 滚动宽度:508(边缘13)

    • 滚动宽度:503(即11)

    • 滚动高度:916(chrome53、safari9)

    • 滚动高度:954(ff49)

    • 滚动高度:922(边缘13,ie11)

  • 分区2

    • 偏移宽度:500(chrome53、ff49、safari9、edge13、ie11)

    • 偏移高度:300(chrome53、ff49、safari9、edge13、ie11)

    • bcr.width:500(chrome53、ff49、safari9、edge13、ie11)

    • bcr.高度:300(chrome53、ff49、safari9)

    • bcr.高度:299.9999694824219(edge13,ie11)

    • 客户端宽度:475(chrome53、ff49、safari9)

    • 客户端宽度:478(边缘13)

    • 客户端宽度:473(ie11)

    • 客户端高度:290(chrome53、ff49、safari9、edge13、ie11)

    • 滚动宽度:475(chrome53、safari9、ff49)

    • 滚动宽度:478(边缘13)

    • 滚动宽度:473(即11)

    • 滚动高度:916(chrome53、safari9)

    • 滚动高度:954(ff49)

    • 滚动高度:922(边缘13,ie11)

  • 分区3

    • 偏移宽度:530(chrome53、ff49、safari9、edge13、ie11)

    • 偏移高度:330(chrome53、ff49、safari9、edge13、ie11)

    • bcr.宽度:265(chrome53、ff49、safari9、edge13、ie11)

    • bcr.高度:165(chrome53、ff49、safari9、edge13、ie11)

    • 客户端宽度:505(chrome53、ff49、safari9)

    • 客户端宽度:508(边缘13)

    • 客户端宽度:503(即11)

    • 客户端高度:320(chrome53、ff49、safari9、edge13、ie11)

    • 滚动宽度:505(chrome53、safari9、ff49)

    • 滚动宽度:508(边缘13)

    • 滚动宽度:503(即11)

    • 滚动高度:916(chrome53、safari9)

    • 滚动高度:954(ff49)

    • 滚动高度:922(边缘13,ie11)

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

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

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

注意:默认垂直滚动条的宽度在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

2024年6月29日 12:07 回复

你的答案