最近在补CSS的基础,看到盒子觉得理解起来比较混乱和困难,于是在网上查了好多资料,然后自己整理之后写了下来。
这次写一下块级元素、块级盒子以及BFC,如果有错误,欢迎大家指正 :)
在页面中,每个元素被表示为一个矩形的方框,这就是盒子。
元素在页面中会生成盒子。
盒子是CSS布局中的基本单位,一张页面是由一个或多个盒子组成的。盒子从内到外由内容(Content)、内边距(Padding)、边框(Border)和外边距(Margin)组成,如下图:
同时,盒子会为其子孙创建包含块(containing block),用于计算内部盒子的大小及位置,由元素样式的position属性确定,这点之后的文章会讨论。
盒子分为多种类型,在没有CSS干预的情况下,它的类型由元素的类型决定,CSS的display属性能够修改它的类型。
块级元素和盒子
display的值为block、table或者list-item的元素是块级元素(block level element),它们会生成块级盒子(block level box)并且参加块级格式化上下文(Block Formatting Context,BFC)。
块级盒子能够设置宽和高,它被定义为放在其他盒子上面的盒子,对外布局的影响主要表现为在它之前和之后的内容都不能和它处于同一行。
默认属于块级盒子的元素主要有:
- 地址(address);
- 块引用(blockquote);
- 居中对其块(center);
- 目录列表(dir);
- 常用块级(div);
- 定义列表(dl)、定义列表描述(dd)、定义列表声明(dt);
- 交互表单(form)、表单控制组(fieldest);
- 大标签(h1)、副标签(h2)、3级标签(h3)、4级标签(h4)、5级标签(h5)、6级标签(h6);
- 水平分隔线(hr);
- 菜单列表(menu);
- 可选脚本内容(noscript);
- 排序列表(ol)、非排序列表(ul)、列表项(li);
- 段落(p);
- 格式化文本(pre);
- 表格(table);
块级元素内嵌套
除了部分块级元素之外,其他的块级元素中能够自由嵌套其他块级元素:
- h1、h2、h3、h4、h5、h6、caption和p元素只能嵌套内联元素;
- hr元素内不能嵌套其他元素;
- dt元素只能被嵌套在dl中;
- ul和ol元素的子级元素必须是li;
- dl元素的子级元素必须是dt或者dl元素;
- table元素的子级元素必须是caption或者thead、tbody、tfooter等元素,他们的子级必须是tr元素,之后才能是th或者td元素;
所以在日常使用中会遇到p元素嵌套div导致页面错误的情况,如下图:
this is a p
this is a div
复制代码
div标签会将p标签从中间断开,和
块级盒模型
块级盒子模型分为W3C标准模型和IE标准模型,可以使用CSS的box-sizing属性控制。
W3C标准模型
W3C标准模型的盒子模型对应的box-sizing属性为content-box,它的width和height属性是内容的宽和高,举个例子:
div {
width: 100px;
height: 100px;
padding: 15px;
margin: 15px;
border: 1px solid #000;
box-sizing: content-box;
}
复制代码
从例子中可以看出,给div设定的width和height属性仅仅只是content的宽和高,而不会把padding、border、margin计算在内。
IE标准模型
IE标准模型对应的box-sizing是border-box,它的width属是边框、内边距和内容的宽的和,它的height属是边框、内边距和内容的高的和,举个例子:
div {
width: 100px;
height: 100px;
padding: 15px;
margin: 15px;
border: 1px solid #000;
box-sizing: border-box;
}
复制代码
从例子中可以看到,给div设定的宽度和高度都是100px,但是实际显示出来的效果上,content只有68px,其他的32px被border和padding分走了。
块级格式化上下文(Block Formatting Context,BFC)
BFC 是一块独立的渲染区域,只有它内部的块级盒子参与它的布局。这些块级盒子的布局方式不会受BFC外部布局的影响,同时它们也不会影响BFC外部的布局。
产生BFC
块级格式化上下文中的“块级”两字并不是指BFC是由块级元素产生的,而是指块级元素会参加到BFC的布局中来。
以下几种元素能够在其内部产生BFC:
-
根元素或其他包含它的元素
-
浮动元素,即float的值不为none的元素;
-
绝对定位元素,即position的值为fixed或absolute的元素;
-
overflow不为visible的元素;
-
内联块元素,即display的值为inline-block的元素;
-
弹性元素,即display的值为flex或者inline-flex的元素;
-
网格元素,即display的值为grid或者inline-grid的元素;
-
HTML默认的某些表格元素:
- table,display的值为table;
- th和td,display的值为table-cell;
- caption,display的值为table-caption;
- tr,display的值为table-row;
- tbody,display的值为table-row-group;
- thead,display的值为table-header-group;
- tfooter,display的值为table-footer-group;
-
流式布局根元素,display值为flow-root的元素;
-
contain的值为layout、contain或者strict的元素;
-
多列容器,column-count或者column-width的值不为auto;column-count的值为1也是多列容器;
-
column-span的值为all的元素始终会创建一个BFC;
BFC的布局规则
- BFC内部的块级盒子会在垂直方向一个接一个的堆放,并且相邻的块级盒子的外边距(Margin)会折叠,以最大的一个外边距作为两个盒子之间的距离;
- 计算BFC的高度时,它内部的浮动元素也会被计算进去;
- BFC的区域不会和浮动盒子相重叠;
- BFC内部每个元素的Margin Box的左边都会和包含块的Border Box的左边相接触;在从右往左格式化的情况下,则是每个元素的Margin Box的右边都会和包含块的Border Box的右边相接触;
- BFC在页面上是一个独立的区域,它内部的元素的布局不会和外部元素的布局产生相互影响;
下面让我们来重点分析几条:
外边距折叠
由于参数BFC布局的是块级盒子,所以不出意料的,每个块级盒子占据一行,在垂直方向一个接一个的堆放;
而由于BFC布局规则第一条,相邻块级盒子之间的外边距会折叠,看个例子:
"container">
"red">
"yellow">
"orange">
复制代码
#container {
overflow: auto;
border: 1px solid #000;
width: 100px;
}
#container > div {
width: 50px;
height: 50px;
margin: 15px;
}
div#red {
background-color: red;
}
div#yellow {
background-color: yellow;
}
div#orange {
background-color: orange;
margin-top: 30px;
}
复制代码
就像例子中展示的那样,我们先使用overflow: auto;
使容器生成一个BFC区域,然后给区域里的每个块级元素设置外边距,能够明显的看到,外边距被折叠了,而且orange的上侧外边距大于yellow的下侧外边距,因此这两个块级盒子的间距就以orange的上侧外边距为准。
阻止外边距的折叠的方法有很多,最简单的方法就是将这几个相邻的盒子放在独立的BFC容器中,使它们不再相邻,修改下之前的例子:
"container">
"red">
"yellow">
"orange">
复制代码
#container {
overflow: auto;
border: 1px solid #000;
width: 100px;
}
#container > div {
overflow: auto;
}
#container > div > div {
width: 50px;
height: 50px;
margin: 15px;
}
div#red {
background-color: red;
}
div#yellow {
background-color: yellow;
}
div#orange {
background-color: orange;
margin-top: 30px;
}
复制代码
可以看到,原本折叠的外边距展开了。
浮动元素导致的高度塌陷
在平时的使用中我们有时会遇到这种情况,在子元素被设置为浮动后,父元素会向上塌陷,这个子元素会突破父元素的区域,看个例子:
"container">
"float">
复制代码
#container {
padding: 15px;
background-color: #000;
width: 100px;
}
#float {
width: 50px;
height: 100px;
background-color: red;
float: left;
}
复制代码
根据BFC布局规则第三条,解决这种高度塌陷的方法就是将父元素设置为能够生成BFC的元素,具体的实现方法有很多种,请参考文章之前的内容,修改一下例子:
#container {
padding: 15px;
background-color: #000;
width: 100px;
overflow: auto;
}
复制代码
这里我们将容器的overflow属性设置为auto,使它产生一个BFC区域,计算高度的时候能够包含浮动的子元素。
不和浮动元素重叠
先来看个例子:
"container">
"float">
"child">
复制代码
#container {
padding: 15px;
background-color: #000;
width: 300px;
overflow: auto;
}
#float {
width: 50px;
height: 100px;
background-color: red;
float: left;
}
#child {
width: 100px;
height: 120px;
background-color: yellow;
}
复制代码
在这个例子里,容器的第二个子元素就和浮动的第一个子元素重叠了,想要让它们不重叠,根据BFC布局的第三条,只要让第二个子元素能够生成BFC区域就可以了,修改一下例子:
#child {
width: 100px;
height: 120px;
background-color: yellow;
overflow: auto;
}
复制代码
本文同时收录在我的GitHub博客:
CSS基础——块级元素、块级盒子以及BFC;
未经允许,请勿转载!