offset* 属性
获取元素的布局尺寸和相对于 offsetParent 的位置
属性说明
offset* 系列属性提供了元素布局尺寸和位置的信息,是最常用的元素测量方式。
- offsetWidth - 元素的宽度(包含 border、padding、滚动条,不包含 margin)
- offsetHeight - 元素的高度(包含 border、padding、滚动条,不包含 margin)
- offsetLeft - 元素左边缘相对于 offsetParent 左边缘的距离
- offsetTop - 元素上边缘相对于 offsetParent 上边缘的距离
- offsetParent - 元素的定位父级元素
示例 1:基本测量
将鼠标悬停在下方元素上查看其 offset 属性值
实时数据
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 边框元素
💡 注意
border 会直接增加 offsetWidth 和 offsetHeight 的值。20px 的边框会使元素的总尺寸增加 40px(左右或上下各 20px)。
示例 3:理解 offsetParent
offsetLeft 和 offsetTop 是相对于 offsetParent 的位置
位置信息
💡 关键点
offsetLeft/offsetTop 是元素 border 外边缘到 offsetParent 的 border 内边缘的距离。 因此它包含父元素的 padding 和子元素的 margin。 本例中:offsetLeft = 父元素 padding-left (40px) + 子元素 margin-left (50px) = 90px
示例 4:滚动容器内的元素
滚动操作不会影响 offsetLeft 和 offsetTop
↓ 向下滚动 ↓
内容结束
offsetTop 值
滚动容器时,offsetTop 保持不变。如果需要获取相对于视口的位置,请使用 getBoundingClientRect()
示例 5:动态调整尺寸
拖动滑块调整元素尺寸,观察 offset 属性的变化
实时测量
💡 实现技巧
本示例使用 ResizeObserver 监听元素尺寸变化后再读取 offsetWidth/Height。 直接在修改样式后同步读取可能因为浏览器渲染时机问题导致获取到旧值,ResizeObserver 能确保在尺寸真正变化后触发回调。
浏览器兼容性
| 属性 | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
| offsetWidth/Height | ✓ 全版本 | ✓ 全版本 | ✓ 全版本 | ✓ 全版本 |
| offsetLeft/Top | ✓ 全版本 | ✓ 全版本 | ✓ 全版本 | ✓ 全版本 |
总结
- offsetWidth/offsetHeight = content + padding + border(包含滚动条)
- offsetLeft/offsetTop 相对于 offsetParent,包含 margin
- 这些属性是只读的,需要通过 style 修改元素尺寸
- 滚动操作不影响 offset 值
- 适用于需要获取元素布局尺寸的场景