从一个矩形div开始
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#container {
width: 200px;
height: 200px;
background-color: gray;
padding: 20px;
margin: 20px;
border: 10px dashed #333;
}
</style>
</head>
<body>
<div id="container">hohoho</div>
</body>
</html>
复制代码
页面上显示的结果如下:
该div的标准盒模型如下图:
盒子由四个属性组成,从内到外分别是:content 内容、padding 内填充、border 边框、外边距 margin
最终元素的总宽度计算公式是:
总元素的宽度=宽度+左填充+右填充+左边框+右边框+左边距+右边距
元素的总高度最终计算公式是:
总元素的高度=高度+顶部填充+底部填充+上边框+下边框+上边距+下边距
clientWidth,clientHeight
这些属性提供了元素边框内区域的大小。包括了 “content width” 和 “padding”,但不包括滚动条宽度。所以上述例子中的clientWidth,clientHeight都是240(200+20+20)。当我们加上一个300 * 300的内部元素之后:
<style>
* {
margin: 0;
padding: 0;
}
#container {
width: 200px;
height: 200px;
background-color: gray;
padding: 20px;
margin: 20px;
border: 10px dashed #333;
overflow: auto;
}
#text {
width: 300px;
height: 300px;
background: #f5f5f5;
}
</style>
<body>
<div id="container">
<div id="text">hohoho</div>
</div>
</body>
复制代码
此时的 clientWidth = clientHeight = 200 + 20 + 20 - 17 = 223,chrome浏览器滚动条默认宽度为17
在进行页面布局的时候尽量使用 document.documentElement 元素的 clientWidth/clientHeight 属性来替换window.innerWidth/innerHeight,大多数情况下我们的排版、绘制是在除滚动条以外的可见区域;
在某些场景下会在 overflow 显示和隐藏间切换,页面会因为有滚动条和没滚动条带来的宽度不同而跳动,这时可以使用 clientWidth/clientHeight 加上一个padding(滚动条的宽度)重新生成没有滚动条的 width/height 来解决跳动问题;
scrollWidth,scrollHeight
该属性也是提供了元素边框内区域的大小,但它们还包括滚动出(隐藏)的部分,也包括滚动条宽度在内。上述例子中的 scrollWidth = scrollHeight = 300 + 20 + 20 = 340
可以发现 scrollWidth 只有320,在页面上可以找到原因(右内边距失效了),而window.getComputedStyle(div).padding = window.getComputedStyle(div).paddingRight = '20px',具体失效的原因请参考css规范中的 #### 10.3.3. Block-level, non-replaced elements in normal flow
里面提到当"over-constrained"时如果 'dir' 是 'ltr' 时就会忽略右填充或右边距而重新计算一个值(但是不清楚为何重新计算了而 window.getComputedStyle(div).paddingRight 获取到的值仍然是 '20px' ),如果我们改为 'rtl' 时左边也会出现这种情况:
可以通过设置内部元素的 display,或者加伪元素的方式来使其显示正常,不展开讨论
offsetWidth,offsetHeight
这两个属性相对较简单。它是元素的完整大小(包括边框),元素的大小除了描述盒模型时一般不会包括外边距,例子中的 offsetWidth = offsetHeight = 200 + 20 + 20 + 10 + 10 = 260
clientLeft,clientTop,offsetLeft,offsetTop,scrollLeft,scrollTop
clientLeft,clientTop:是元素内到边框外的距离(不等于边框),例如 'dir' 特性为 'rtl' 的值还包括滚动条的宽度,如:
offsetLeft,offsetTop:是相对于 offsetParent
(是最接近的祖先:position
为 absolute
,relative
或 fixed
; 或 <td>
,<th>
,<table>
;或 <body>
) 的边缘的坐标,所以元素的外边距被计算在内,如:
scrollLeft,scrollTop:从元素的左上角开始,滚动出元素的左半部分/上半部分的值,如:
通过以上示例可以实现 文字过长时截断隐藏(悬停时完全显示),未超长时没有悬停效果