CSS 基础盒模型
CSS 盒模型是页面布局的基础。
当对一个文档进行布局的时候,浏览器的渲染引擎会根据标准之一的 CSS 基础框盒模型(CSS basic box model),将所有元素表示为一个个矩形的盒子(box)。CSS 决定这些盒子的大小、位置以及属性(例如颜色、背景、边框尺寸…)。
每个盒子由四个部分(或称区域)组成,分别为:内容区域 content area、内边距区域 padding area、边框区域 border area 、外边距区域 margin area,分别对应 width、height
、padding
、border
、margin
。
注意 box-sizing
这个 CSS 属性。
content-box
(W3C 盒模型)是默认值。如果你设置一个元素的宽为100px
,那么这个元素的内容区会有100px
宽,并且任何边框和内边距的宽度都会被增加到最后绘制出来的元素宽度中。也就是说,最终盒子的宽高 >= 设置的宽高。border-box
(IE 盒模型)告诉浏览器:你想要设置的边框和内边距的值是包含在width
内的。也就是说,如果你将一个元素的width
设为100px
,那么这100px
会包含它的border
和padding
,内容区的实际宽度是width
减去(border
+padding
)的值。大多数情况下,这使得我们更容易地设定一个元素的宽高。
看下面的例子。
<div class="content-box">Content box</div>
<br>
<div class="border-box">Border box</div>
div {
width: 160px;
height: 80px;
padding: 20px;
border: 8px solid red;
background: yellow;
}
.content-box {
box-sizing: content-box;
/* Total width: 160px + (2 * 20px) + (2 * 8px) = 216px
Total height: 80px + (2 * 20px) + (2 * 8px) = 136px
Content box width: 160px
Content box height: 80px */
}
.border-box {
box-sizing: border-box;
/* Total width: 160px
Total height: 80px
Content box width: 160px - (2 * 20px) - (2 * 8px) = 104px
Content box height: 80px - (2 * 20px) - (2 * 8px) = 24px */
}
从结果可以看得比较明白,border-box
的总宽高不会超过设定的 width
和 height
,而 content-box
的大小是不确定的,会受到 border
和 padding
影响。
布局和包含块
元素的尺寸及位置,常常会受它的包含块所影响。对于一些属性,例如 width
, height
, padding
, margin
,绝对定位元素的偏移值 (比如 position
被设置为 absolute
或 fixed
),当我们对其赋予百分比值时,这些值的计算值,就是通过元素的包含块计算得来。
position
确定一个元素的包含块的过程完全依赖于这个元素的 position
属性。我们先看看 position
属性。
static
该关键字指定元素使用正常的布局行为,即元素在文档常规流中当前的布局位置。此时top
,right
,bottom
,left
和z-index
属性无效。relative
该关键字下,元素先放置在未添加定位时的位置,再在不改变页面布局的前提下调整元素位置(因此会在此元素未添加定位时所在位置留下空白)。position:relative
对table-*-group
,table-row
,table-column
,table-cell
,table-caption
元素无效。absolute
不为元素预留空间,通过指定元素相对于最近的非static
定位祖先元素的偏移,来确定元素位置。绝对定位的元素可以设置外边距(margins
),且不会与其他边距合并。fixed
不为元素预留空间,而是通过指定元素相对于屏幕视口(viewport
)的位置来指定元素位置。元素的位置在屏幕滚动时不会改变。打印时,元素会出现在的每页的固定位置。fixed
属性会创建新的层叠上下文。当元素祖先的transform
属性非none
时,容器由视口改为该祖先。sticky
盒位置根据正常流计算(这称为正常流动中的位置),然后相对于该元素在流中的 flow root(BFC)和 containing block(最近的块级祖先元素)定位。在所有情况下(即便被定位元素为 table 时),该元素定位均不对后续元素造成影响。当元素 B 被粘性定位时,后续元素的位置仍按照 B 未定位时的位置来确定。position: sticky
对 table 元素的效果与 position: relative 相同。 粘性定位可以被认为是相对定位和固定定位的混合。元素在跨越特定阈值前为相对定位,之后为固定定位。 它可以很方便的实现 IOS 中的列表 title 吸顶效果。
<head>
<style>
#box {
height: 5000px;
}
#sti {
position: sticky;
top: 100px;
}
p {
height: 1000px;
}
</style>
</head>
<body>
<div id="box" class="box1" name="lxfriday">
<p>hello div</p>
<div id="sti">sti</div>
</div>
</body>
确定包含块
确定一个元素的包含块的过程完全依赖于这个元素的 position
属性:
- 如果
position
属性为static
或relative
,包含块就是由它的最近的祖先块元素(inline-block
、block
、list-item
),或者 BFC(table
、flex
、grid
) 的内容区的边缘组成的。 - 如果
position
属性为absolute
,包含块就是由它的最近的position
的值不是static
(也就是值为fixed
,absolute
,relative
或sticky
)的祖先元素的内边距区的边缘组成。 - 如果
position
属性是fixed
,可以认为包含块就是视口 viewport。
注意: 根元素(<html>
)所在的包含块是一个被称为初始包含块的矩形,可认为是视口 viewport。.
根据包含块计算百分值
如果某些属性被赋予一个百分值的话,它的计算值是由这个元素的包含块计算而来的。这些属性包括盒模型属性和偏移属性:
-
要计算
height
top
及bottom
中的百分值,是通过包含块的height
的值。如果包含块的height
值会根据它的内容变化,而且包含块的position
属性的值被赋予relative
或static
,那么,这些值的计算值为 0,也就是说包含块自身能先确定高度才可以让子元素的百分比计算生效。看下面例子,
.con
这个父元素没有设置高度,.c1
子元素设置了高度500px
,.c2
设置的是百分比高度,根据上面的规则, 由于父元素.con
的position
为static
,所以子元素设置百分比高度将会无效。
<head>
<style>
.con {
background-color: red;
}
.c1 {
background-color: cyan;
height: 500px;
}
.c2 {
background-color: green;
height: 100%;
}
</style>
</head>
<body>
<div class="con">
<div class="c1"></div>
<div class="c2"></div>
</div>
</body>
- 要计算
width
,left
,right
,padding
,margin
这些属性由包含块的width
属性的值来计算它的百分值。
感谢阅读,欢迎关注我的公众号 云影sky,带你解读前端技术。
参考: