一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第28天,点击查看活动详情
我正在参加 码上掘金体验活动,详情:show出你的创意代码块
一个元素的尺寸和位置经常受其包含块(containing block)的影响。
一般情况下,包含块就是这个元素最近的祖先块级元素的内容区或最近的开启BFC的祖先元素的内容区,但也不是总是这样
当一个客户端代理(比如说浏览器)展示一个文档的时候,对于每一个元素,它都产生了一个盒子。
每一个盒子都被划分为四个区域:
- 内容区
- 内边距区
- 边框区
- 外边距区
包含块的确定
| 元素分类 | 包含块 |
|---|---|
| 标准流中布局的元素或定位值为relative或sticky的定位元素 | 最近的祖先元素的内容区或最近的开启BFC的元素的内容区 |
| position的值为absolute的定位元素 | 最近的那个定位祖先元素 |
| position的值为fixed的定位元素 | 视口 |
| 对于绝对定位元素 (也就是position的值为fixed或absolute的定位元素) | 可以是最近的那个transform或perspective的值不为none的祖先元素 |
根元素(
<html>)所在的包含块是一个被称为初始包含块的矩形, 其本质上就是视口(viewport)
包括块的作用
- 我们在设置元素的
width, height, margin, padding, top, bottom, left, right的值为百分比的时候,所参照的对应值就是由这个元素的包含块计算而来的 - 产生定位的元素,也是参照其对应的包含块的
| 属性 | 参照 |
|---|---|
height, top, bottom | 包含块的 height如果包含块的height为auto,且包含块没有脱标,那么这些值的计算值为auto,表现为0 |
width, margin, padding, left, right | 包含块的 widthmargin和padding四个方向的值其在设置百分比的时候,其实参照包含块的width |
示例
- 在标准流中,普通元素的包含块就是其父元素
.container {
width: 300px;
height: 300px;
background-color: skyblue;
}
/* div.box的包含块为div.container */
.box {
/* 300 * 50% = 150px */
width: 50%;
/* 300 * 50% = 150px */
height: 50%;
/* 300 * 10% = 30px */
margin: 10%;
/* 300 * 10% = 30px */
padding: 10%;
background-color: gray;
}
- 只有块级元素或开启了BFC的元素,才可能形成包含块
.container {
display: inline;
width: 300px;
height: 300px;
background-color: skyblue;
}
/* 此时div.box的父元素不是一个块级元素,所以其包含块是viewport */
.box {
/* width of viewport * 50% */
width: 50%;
/*
viewport的宽度是由div.box撑开的
所以height的值为auto,表现为0
*/
height: 50%;
/* width of viewport * 10% */
margin: 10%;
/* width of viewport * 10% */
padding: 10%;
background-color: gray;
}
- 如果包含块是content-box,其宽高会受其padding和border的影响
但是如果包含块是border-box, 就不会存在这个问题
.outter {
/*
此时因为存在padding
所以div.outter变成了 640 * 640的容器
*/
position: absolute;
width: 600px;
height: 600px;
padding: 20px;
background-color: purple;
}
.container {
width: 300px;
height: 300px;
background-color: skyblue;
}
.box {
position: absolute;
/* 640 * 50% = 320 */
width: 50%;
/* 640 * 50% = 320 */
height: 50%;
/* 640 * 10% = 64 */
margin: 10%;
/* 640 * 10% = 64 */
padding: 10%;
/* 640 * 10% = 64 */
left: 10%;
/* 640 * 10% = 64 */
top: 10%;
background-color: gray;
}
.outter {
/*
如果父元素是border-box, 那么其实际的宽度和高度就不会被padding或border给撑开了
在这里,其实际宽度就是600 * 600
*/
box-sizing: border-box;
position: absolute;
width: 600px;
height: 600px;
padding: 20px;
background-color: purple;
}
.container {
width: 300px;
height: 300px;
background-color: skyblue;
}
/* div.box的包含块为 div.outter */
.box {
position: absolute;
/* 600px * 50% = 300px */
width: 50%;
/* 600px * 50% = 300px */
height: 50%;
/* 600px * 10% = 60px */
margin: 10%;
/* 600px * 10% = 60px */
padding: 10%;
/* 600px * 10% = 60px */
left: 10%;
/* 600px * 10% = 60px */
top: 10%;
background-color: gray;
}
- 固定定位元素是相对于其包含块的,而默认包含块为viewport
.outter {
transform: scale(1);
width: 600px;
height: 600px;
padding: 20px;
background-color: purple;
}
.container {
width: 300px;
height: 300px;
background-color: skyblue;
}
.box {
/*
当元素是绝对定位元素
也就是position属性值为fixed或absolute的时候
对于absolute元素,其包含块就是最近的那个定位祖先元素,
或者是transform值不为none或prespective的值不为none的那个祖先元素
对于fixed元素,其包含块就是viewport,
或者是transform值不为none或prespective的值不为none的那个祖先元素
所以在这里 div.box的包含块是参照于div.outter
此时div.box的定位也是参照于div.outter的,不再是viewport
*/
position: fixed;
width: 50%;
height: 50%;
margin: 10%;
padding: 10%;
left: 10%;
top: 10%;
background-color: gray;
}