包含块,在前端开发中有着很重要的地位,很多内容的计算都离不开包含块,但是在学习前端内容的时候又会被忽略,下面我们来介绍一下。
为何会总结包含块呢
最近突然用到了offsetLeft, offsetTop
属性,他们表示当前元素与offsetParent
获取到的元素的偏移距离。我一直以为offsetParent
获取的元素是当前元素的包含块元素。查阅一些资料和写一些demo才发现不是这样的。
offsetParent
返回一个指向最近的(指包含层级上的最近)包含该元素的定位元素(相对定位也可以,除了静态定位不行,其他定位都行)或者最近的 table
, td
, th
, body
元素。
注意offsetParent
获取的并不是元素的包含块。需要严格按照他的定义来。防止和包含块搞混淆。 如果获取的是包含块,那么下面p.offsetParent就是div了,而不是body。
xml
js
<style>
* {
padding: 0;
margin: 0;
}
div {
width: 200px;
height: 200px;
border: 1px solid #000;
margin: 30px;
}
p {
margin: 20px;
width: 20px;
height: 20px;
background: #888;
}
</style>
</head>
<body>
<div>
<!-- offsetLeft 51 包含块是body ,可以通过offsetParent获取-->
<p></p>
</div>
</body>
包含块
一个元素的尺寸和位置经常受其包含块(containing block)的影响 。以前写过一篇文章 css单位%在不同属性中的依据计算。
包含块就是这个元素最近的祖先块元素的内容区域(除了定位元素,其他的都是最近的块级父元素) 。
需要注意一下absolute, fixed
定位的一些父元素非定位的特殊情况,例如transform
等。其实这种情况也是定位偏移的参考,和父元素定位的情况是一样的。以前我们总是说"子绝父相",但是现在也可以使用下面这些方式让绝对定位的元素作为偏移的参考了。
xml
js
<style>
* {
padding: 0;
margin: 0;
}
div {
width: 200px;
height: 200px;
border: 1px solid #000;
margin: 30px;
/* transform: translate(0); */
}
p {
width: 20px;
height: 20px;
background: #888;
position: absolute;
left: 30px;
}
</style>
</head>
<body>
<div>
<p></p>
</div>
</body>
以前在mdn上只看见了fixed
定位中当元素祖先的 transform
、perspective
、filter
或 backdrop-filter
属性非 none
时,偏移量将参考该祖先元素。但是不知道absolute
定位也有这种效果,对于祖先元素设置了这些属性。一直以为只有祖先元素设置了定位,当前绝对定位元素才会参考祖先元素偏移。
总结
经过这次简单总结,搞清楚了几件事情。
- 包含块如何查找。除了定位元素,包含块都是当前元素最近的块级祖先元素。
- offsetParent如何查找。设置了任何定位的祖先元素或者最近的
table
,td
,th
,body
元素 - absolute定位元素还可以参考设置了
transform
、perspective
、filter
或backdrop-filter
属性非none
时祖先元素定位。 - 元素的位置和尺寸设置为百分比时,例如
width
,height
,padding
,margin
,绝对定位元素的偏移值,这些值的计算值,就是通过元素的包含块计算得来。
往期年度总结
往期文章
- 反调试吗?如何监听devtools的打开与关闭
- 因为原生,选择一家公司(前端如何防笔试作弊)
- 结合开发,带你熟悉package.json与tsconfig.json配置
- 如何优雅的在项目中使用echarts
- 如何优雅的做项目国际化
- 近三个月的排错,原来的憧憬消失喽
- 带你从0开始了解vue3核心(运行时)
- 带你从0开始了解vue3核心(computed, watch)
- 带你从0开始了解vue3核心(响应式)
- 3w+字的后台管理通用功能解决方案送给你
- 入职之前,狂补技术,4w字的前端技术解决方案送给你(vue3 + vite )