在网页前端开发中,我们可以通过 Javascript 获取元素的位置、宽高,HTML DOM 提供了多个相关属性,它们是:
clientLeft、clientTop、clientWidth、clientHeight;
offsetLeft、offsetTop、offsetWidth、offsetHeight;
scrollLeft、scrollTop、scrollWidth、scrollHeight。
这些看上去都可以获得位置、宽高,那么这些属性有什么不同呢,此篇文章就会对此做出解释。
为了便于理解,我们需要先做个测试用的 HTML 页面,代码如下:
<body>
<!-- 元素 1 -->
<div style="display: inline-block; border: 20px dashed gray;">
<!-- 元素 2 -->
<div style="border: 20px solid black; margin: 30px; padding: 30px;">
<!-- 元素 3 -->
<div style="width: 100px; height: 100px; padding: 30px; white-space: nowrap; border: 20px solid green; background: cyan; overflow: scroll;">
这是一个 div 元素,这是一个 div 元素<br />
这是一个 div 元素,这是一个 div 元素<br />
这是一个 div 元素,这是一个 div 元素<br />
这是一个 div 元素,这是一个 div 元素<br />
这是一个 div 元素,这是一个 div 元素<br />
这是一个 div 元素,这是一个 div 元素<br />
这是一个 div 元素,这是一个 div 元素<br />
这是一个 div 元素,这是一个 div 元素<br />
这是一个 div 元素,这是一个 div 元素<br />
这是一个 div 元素,这是一个 div 元素<br />
</div>
</div>
</div>
</body>
最外层是一个黑色边框的 div 元素,我们称其为“元素 1”,其包裹了一个黑色边框的 div 元素,我们称其为“元素 2”,最里面也是一个 div 元素,绿色边框,里面有多行的文本内容,我们称其为“元素 3”;我们所要研究的那些属性依赖于边距、边框等要素,所以这里面我们特意给这些 div 元素加了相关的属性,此页面在浏览器中看上去是下面这样的:

如图所示,我已将重要的信息标注了出来,Left、Top、Width、Height 这四个词的基本意思肯定都知道,那么我就把 client、offset、scroll 这三个当作类别来解释。
【client】
这类宽高简单理解为包含了元素的内边距,不包含滚动条:

但是要注意,这类的偏移位置在某些情况下会计算滚动条的宽高,比如该元素的文本方向是自右向左时:

使用 CSS 属性,direction: rtl;
可使滚动条位于左边,不过通常情况下,可以把 client 类的偏移位置理解为:元素内边距的外边至元素外边框的距离,绝大多数情况下也是等同于元素边框的宽度,反正基本上不会遇到自右向左文本的时候,而且水平滚动条也不会出现在上边框的位置。
【offset】
这类的宽高可以简单理解为包含了边框、内边距、滚动条的宽高;这类的偏移位置指的是该元素相对于其 offsetParent 元素的偏移位置,offsetParent 指的是离该元素最近的有明确定位的父级元素,“有明确定位的元素”可以是:
- 具有
position: absolute;
CSS 属性的,但不能是 fixed - 因过时属性 zoom 产生了效果的,使用了不为默认值的 zoom 属性
- td、th、table 这类自身有静态定位属性的
如果该元素向上找不到任何有明确定位的父级元素,就会取 body 元素当作该元素的 offsetParent 参考对象;了解了计算 offset 类偏移位置需要依赖 offsetParent 元素做参考对象后,接下来就好理解下面关于 offset 类的宽高、位置图示了:

如图所示,我给元素 2 添加了 position: absolute;
属性,这样元素 2 就成了元素 3 的 offsetParent;那么 offset 偏移位置可以简单理解为该元素的外边框至其 offsetParent 元素的内边距外边的距离或至其 offsetParent 元素内边框的距离,包含了该元素的外边距。
【scroll】
这类的宽高可以简单理解为该元素内容区域可见的、不可见的、内边距的宽高,不含滚动条、边框,下图展示了假设元素 3 的内容滚动到了最下边与最右边时的场景:

上图为了更好地释义,所以虚拟展示了元素溢出的内容,这是我假想出来的,scroll 类的偏移位置可以简单理解为剩余内容部分的宽高加上滚动条的宽高,也不包含边框。
关于 scroll 类可能还会有另一种情况,假如你强行让元素显示内容溢出的部分,不让它出现滚动条,这时 scroll 类的属性计算方式会有点不一样,它的宽高好像会多加一边的内边距宽高,不过想必用到滚动功能的地方不会强行让它显示溢出吧,所以你大可简单地把元素的 scroll 类的宽高理解为只说的是它的内容区域,包含内边距,不含边框,但 scroll 类的偏移位置计算了滚动条的宽高。
浏览器环境:5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0