offset* 属性

获取元素的布局尺寸和相对于 offsetParent 的位置

属性说明

offset* 系列属性提供了元素布局尺寸和位置的信息,是最常用的元素测量方式。

  • offsetWidth - 元素的宽度(包含 border、padding、滚动条,不包含 margin)
  • offsetHeight - 元素的高度(包含 border、padding、滚动条,不包含 margin)
  • offsetLeft - 元素左边缘相对于 offsetParent 左边缘的距离
  • offsetTop - 元素上边缘相对于 offsetParent 上边缘的距离
  • offsetParent - 元素的定位父级元素

示例 1:基本测量

将鼠标悬停在下方元素上查看其 offset 属性值

悬停我

实时数据

offsetWidth: 0px
offsetHeight: 0px
offsetLeft: 0px
offsetTop: 0px
const box = document.getElementById('box');
console.log(box.offsetWidth);   // 元素宽度
console.log(box.offsetHeight);  // 元素高度
console.log(box.offsetLeft);    // 相对于 offsetParent 的左侧距离
console.log(box.offsetTop);     // 相对于 offsetParent 的顶部距离

示例 2:border 的影响

offsetWidth 和 offsetHeight 包含 border 的宽度

无边框
20px 边框

无边框元素

offsetWidth: 0px
border: 0px

20px 边框元素

offsetWidth: 0px
border: 20px × 2 = 40px

💡 注意

border 会直接增加 offsetWidth 和 offsetHeight 的值。20px 的边框会使元素的总尺寸增加 40px(左右或上下各 20px)。

示例 3:理解 offsetParent

offsetLeft 和 offsetTop 是相对于 offsetParent 的位置

offsetParent (position: relative)
子元素

位置信息

子元素 offsetLeft: 0px
子元素 offsetTop: 0px
子元素 margin-left: 50px
子元素 margin-top: 30px
父元素 padding-left: 40px

💡 关键点

offsetLeft/offsetTop 是元素 border 外边缘到 offsetParent 的 border 内边缘的距离。 因此它包含父元素的 padding 和子元素的 margin。 本例中:offsetLeft = 父元素 padding-left (40px) + 子元素 margin-left (50px) = 90px

示例 4:滚动容器内的元素

滚动操作不会影响 offsetLeft 和 offsetTop

↓ 向下滚动 ↓

目标元素

内容结束

offsetTop 值

元素 offsetTop: 0px
滚动位置: 0px

滚动容器时,offsetTop 保持不变。如果需要获取相对于视口的位置,请使用 getBoundingClientRect()

示例 5:动态调整尺寸

拖动滑块调整元素尺寸,观察 offset 属性的变化

150 × 150

实时测量

offsetWidth: 0px
offsetHeight: 0px

💡 实现技巧

本示例使用 ResizeObserver 监听元素尺寸变化后再读取 offsetWidth/Height。 直接在修改样式后同步读取可能因为浏览器渲染时机问题导致获取到旧值,ResizeObserver 能确保在尺寸真正变化后触发回调。

浏览器兼容性

属性 Chrome Firefox Safari Edge
offsetWidth/Height ✓ 全版本 ✓ 全版本 ✓ 全版本 ✓ 全版本
offsetLeft/Top ✓ 全版本 ✓ 全版本 ✓ 全版本 ✓ 全版本

总结

  • offsetWidth/offsetHeight = content + padding + border(包含滚动条)
  • offsetLeft/offsetTop 相对于 offsetParent,包含 margin
  • 这些属性是只读的,需要通过 style 修改元素尺寸
  • 滚动操作不影响 offset 值
  • 适用于需要获取元素布局尺寸的场景