DOM元素尺寸详解:盒模型与宽高属性

前端 潘老师 1周前 (04-14) 14 ℃ (0) 扫码查看

很多前端开发朋友对于理解DOM元素的尺寸以及相关的盒模型、宽高属性仍有不足,但它们直接影响页面的布局和显示效果,今天就来深入探讨一下这些知识。

一、深入理解两种盒模型

在CSS中,box-sizing属性用于控制盒模型的类型,主要有两种盒模型:标准盒模型和IE盒模型。

(一)标准盒模型(content-box)

在标准盒模型下,widthheight仅仅表示元素内容区域的尺寸。假设我们设置了如下样式:

.box {
  width: 200px;
  height: 100px;
  padding: 20px;
  border: 10px solid;
  margin: 30px;
}

用图形来表示的话,就是这样:

+----------------------------------------+
| Margin (30px)                          |
|  +----------------------------------+  |
|  | Border (10px)                    |  |
|  |  +----------------------------+  |  |
|  |  | Padding (20px)             |  |  |
|  |  |  +----------------------+  |  |  |
|  |  |  | Content (200px)      |  |  |  |
|  |  |  +----------------------+  |  |  |
|  |  |                            |  |  |
|  |  +----------------------------+  |  |
|  |                                  |  |
|  +----------------------------------+  |
+----------------------------------------+

从这个图中可以清晰地看到,计算元素的总宽度时,需要把内容宽度、左右padding、左右border以及左右margin都加起来,即总宽度 = 200 + 20×2 + 10×2 + 30×2 = 320px。

(二)IE盒模型(border-box)

IE盒模型(border-box)和标准盒模型有所不同,这里的widthheight表示的是内容、padding和border的总和。还是以上面的样式为例,用图形表示如下:

+----------------------------------------+
| Margin (30px)                          |
|  +----------------------------------+  |
|  | Border (10px) + Padding (20px)   |  |
|  |  +----------------------------+  |  |
|  |  | Content (实际: 140px)       |  |  |
|  |  | (200 - 20*2 - 10*2 = 140)  |  |  |
|  |  +----------------------------+  |  |
|  |                                  |  |
|  +----------------------------------+  |
+----------------------------------------+

在IE盒模型下,计算总宽度时,只需要把设置的width和左右margin相加就行,所以总宽度 = 200 + 30×2 = 260px ,这里内容的实际宽度则是通过设置的width减去左右padding和左右border得到的,即200 – 20×2 – 10×2 = 140px。

二、DOM元素的宽高属性详解

了解了盒模型之后,接下来看看与DOM元素宽高相关的几个属性。

(一)offsetWidth / offsetHeight

这个属性包含了内容的width/heightpadding以及border,但不包含margin。以之前设置的样式为例:

  • content-box盒模型下,offsetWidth的计算方式为:内容宽度 + 左右padding + 左右border,即200 + 20×2 + 10×2 = 260px。
  • border-box盒模型下,offsetWidth就等于设置的width,也就是200px。

(二)clientWidth / clientHeight

clientWidthclientHeight属性包含内容的width/heightpadding,但不包含bordermargin。同样以之前的样式为例:

  • content-box盒模型下,clientWidth = 内容宽度 + 左右padding,即200 + 20×2 = 240px。
  • border-box盒模型下,clientWidth = 设置的width – 左右border,即200 – 10×2 = 180px。

(三)getBoundingClientRect

getBoundingClientRect方法返回的widthheight等于 (内容 + padding + border) × transform缩放系数,并且这个宽高与盒模型的设置无关。它的主要作用是返回元素相对于视口的精确几何信息,返回值是一个DOMRect对象,包含8个属性:

{
  x:       // 元素左上角X坐标(等同left)
  y:       // 元素左上角Y坐标(等同top)
  left:    // 元素左侧到视口左侧的距离
  top:     // 元素顶部到视口顶部的距离
  right:   // 元素右侧到视口左侧的距离
  bottom:  // 元素底部到视口顶部的距离
  width:   // 元素的实际渲染宽度(含transform)
  height:  // 元素的实际渲染高度(含transform)
}
  1. 坐标系示意图:视口的左上角坐标为(0,0),X轴向右延伸,Y轴向下延伸。元素的左上角坐标为(left, top) ,并且满足rect.right === rect.left + rect.widthrect.bottom === rect.top + rect.height这样的关系。
  2. 性能注意事项:在使用getBoundingClientRect方法时,要注意性能问题。频繁调用这个方法会强制同步布局,导致性能下降。所以最好批量读取相关属性,例如:
// (触发两次重排)
const width = el.getBoundingClientRect().width;
const height = el.getBoundingClientRect().height;

// (单次重排)
const rect = el.getBoundingClientRect();
const width = rect.width;
const height = rect.height;

后面这种方式连续读取多个属性,只会触发一次重排,能有效提升性能。

(四)scroll相关属性和方法

  1. scrollHeight & scrollWidthscrollHeight等于内容的实际高度加上paddingscrollWidth等于内容的实际宽度加上padding。比如下面这个例子:
<div id="container" style="height:200px; overflow-y:scroll">
  <div style="height:800px; padding:20px"></div>
</div>
<script>
  console.log(container.scrollHeight); // 800 + 20*2 = 840
  // 如果设置overflow-y:hidden,container.scrollHeight = 800 + 20 = 820
</script>
  1. scrollTop & scrollLeftscrollTop表示元素内容向上滚动的距离,scrollLeft表示元素内容向左滚动的距离。判断元素是否滚动到底部,可以通过element.scrollTop >= scrollHeight - clientHeight这个式子来判断,同理,判断是否滚动到最右侧,可以用element.scrollLeft >= scrollWidth - clientWidth
  2. scrollTo方法:使用scrollTo方法可以实现平滑滚动效果,比如下面这样:
// 原生平滑滚动
element.scrollTo({
  top: 500,
  behavior:'smooth'
});
  1. scrollTopMax / scrollLeftMax:目前只有火狐浏览器支持这两个属性。scrollTopMax表示最大可滚动距离,即scrollHeight - clientHeight,常用于检测元素是否滚动到底部;scrollLeftMax表示最大水平滚动距离,即scrollWidth - clientWidth,可用于横向滚动限制检测。兼容性方面,Chrome、Safari、Edge和IE都不支持这两个属性,只有Firefox 44及以上版本支持 。

通过对DOM元素盒模型和各种宽高属性的详细介绍,希望大家能在前端开发中更准确地把握页面布局,避免因尺寸计算错误导致的显示问题。

兼容性对照表

属性/方法 Chrome Firefox Safari Edge IE
scrollTopMax ✅ 44+

版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/front/17203.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】