文章目录
BFC
是什么
- 全程:Block Formatting Context,即“块级格式化上下文”
- 一个完全独立的空间(布局环境),让空间里的子元素不会影响到外面的布局
规则
- BFC是一个块级元素,会在垂直方向一个接一个的排列
- 是页面中的一个隔离的独立容器,容器里的标签不会影响到外部标签
- 如果两个块级元素属于同一个BFC,它们的上下margin会重叠(margin塌陷),以较大的为准。但是,如果两个块级元素分别在不同BFC中,它们的上下边距就不会重叠了,而是两者之和
- 计算BFC的高度时,浮动元素也参与计算。BFC可以包含浮动元素(可以利用BFC清除浮动)
- BFC的区域不会与浮动的元素区域重叠,即,不会与浮动盒子产生交集,而是紧贴浮动边缘
注意:同一个元素不能同时存在于两个 BFC 中。
如何触发
常用的:
作用
- 解决浮动元素令父元素高度坍塌的问题
方法:给父元素开启BFC
原理:计算BFC的高度时,浮动子元素也参与计算
- 非浮动元素被浮动元素覆盖
方法:给非浮动元素开启BFC
原理:BFC的区域不会与float box重叠
- 两栏自适应布局
方法:给固定栏设置固定宽度,给不固定栏开启BFC。
原理:BFC的区域不会与float box重叠
左列浮动。右列设置 overflow: hidden; 触发BFC ,即,float + overflow:hidden
- 外边距垂直方向重合的问题
方法:给上box或者下box任意一个包裹新的box并开启BFC
原理:属于同一个BFC的两个相邻的Box的margin会发生重叠。
上述作用的演示:一次弄懂css的BFC - 知乎 (zhihu.com)
其他
IFC(行级格式化上下文)- inline 内联
GFC(网格布局格式化上下文)- display: grid
FFC(自适应格式化上下文)- display: flex或display: inline-flex
参考:
面试官:请说说什么是BFC?大白话讲清楚 - 掘金 (juejin.cn)
一次弄懂css的BFC - 知乎 (zhihu.com)
CSS中的BFC是什么?怎么用? - 掘金 (juejin.cn)
position
具有以下属性:
relative
:相对之前自身的位置发生偏移,且原来的位置仍然被占据,不脱离文档流。偏移时,可能覆盖其他元素。body默认是relative,子绝父相。absolute
:脱离文档流,且相对于包含块进行偏移(包含块:最近一级外层元素position
不为static
的元素)。fixed
:脱离文档流,并且相对于视窗进行定位。static
:默认值,取消继承。没有定位。sticky
:css3新增属性值,粘性定位,相当于relative和fixed的混合。最初会被当作是relative,相对原来位置进行偏移;一旦超过一定的阈值,会被当成fixed定位,相对于视口定位。inherit
:继承父元素的position值。
细说css中的position属性 - 知乎 (zhihu.com)
两栏布局
左边宽度固定,右边宽度自适应。
- 利用
flex
布局:将左边元素为固定宽度200px,将右边的元素设置为flex:1 - 利用浮动。左边元素宽度为200px,且向左浮动。右边元素的margin-left为200px,宽度设置为auto(默认为auto,撑满整个父元素)
- 左边元素宽度固定 ,设置向左浮动。右侧元素
overflow: hidden
; 右边触发BFC,BFC的区域不会与浮动元素发生重叠,所以两侧就不会发生重叠。
三栏布局
两边使用 float,中间使用 margin
- 两边固定宽度,中间宽度自适应
- 利用中间元素的margin值控制两边的间距
- 宽度小于左右部分宽度之和时,右侧部分被挤下去
<style>
.wrap {
background: #eee;
overflow: hidden; <!-- 生成BFC,计算高度时考虑浮动的元素 -->
padding: 20px;
height: 200px;
}
.left {
width: 200px;
height: 200px;
float: left;
background: coral;
}
.right {
width: 120px;
height: 200px;
float: right;
background: lightblue;
}
.middle {
margin-left: 220px;
height: 200px;
background: lightpink;
margin-right: 140px;
}
</style>
<div class="wrap">
<div class="left">左侧</div>
<div class="right">右侧</div>
<div class="middle">中间</div>
</div>
两边使用 absolute,中间使用 margin
基于绝对定位的三栏布局:注意绝对定位的元素脱离文档流,相对于最近的已经定位的祖先元素进行定位。无需考虑HTML中结构的顺序.
- 左右两边使用绝对定位,固定在两侧。
- 中间占满一行,通过
margin
和左右两边留出间隔
<style>
.container {
position: relative;
}
.left,
.right,
.main {
height: 200px;
line-height: 200px;
text-align: center;
}
.left {
position: absolute;
top: 0;
left: 0;
width: 100px;
background: green;
}
.right {
position: absolute;
top: 0;
right: 0;
width: 100px;
background: green;
}
.main {
margin: 0 110px;
background: black;
color: white;
}
</style>
<div class="container">
<div class="left">左边固定宽度</div>
<div class="right">右边固定宽度</div>
<div class="main">中间自适应</div>
</div>
flex实现
- 容器设置为
display:flex
; - 盒内元素两端对齐,将中间元素设置为
width:100%
,或者设为flex:1
,即可填充空白 - 盒内元素的高度撑开容器的高度
<style type="text/css">
.wrap {
display: flex;
justify-content: space-between;
}
.left,
.right,
.middle {
height: 100px;
}
.left {
width: 200px;
background: coral;
}
.right {
width: 120px;
background: lightblue;
}
.middle {
background: #555;
width: 100%;
margin: 0 20px;
}
</style>
<div class="wrap">
<div class="left">左侧</div>
<div class="middle">中间</div>
<div class="right">右侧</div>
</div>
面试官:如何实现两栏布局,右侧自适应?三栏布局中间自适应呢? | web前端面试 - 面试官系列 (vue3js.cn)
水平居中(6种方法)
左右两边间隔相等的居中
flex
display: flex;
justify-content: center;
<div class='parent'>
<div class="son">
</div>
</div>
.parent {
display: flex;
justify-content: center;
}
.son {
background: pink;
width: 100px;
height: 100px;
}
绝对定位+margin:auto
- 居中子元素
- 子绝父相,子元素
margin:auto
原理:
top + margin-top + border-top-width + padding-top + height + padding-bottom + border-bottom-width + margin-bottom + bottom = height
上述式子中,top和bottom为0,margin等于auto,此时浏览器为了满足这个等式会把上下的距离均匀分给margin,即达到我们想要的居中效果。横向也是一样的道理。
.father {
position: relative;
width: 500px;
height: 500px;
background-color: blue;
}
.center {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
width: 100px;
height: 100px;
background-color: red;
}
<div class='father'>
<div class="center">
</div>
</div>
绝对定位+margin:负值
原理:对当前元素的position设置为absolute,并且相对于父元素定位。先设置left:50%;top:50%,使当前元素的左上角处于父元素的中心位置。之后再应用负margin特性使其中心位于父元素的中心。因此需要知道子元素的大小。挪动子元素大小的一半。
.father {
position: relative;
width: 500px;
height: 500px;
background-color: blue;
}
.center {
width: 200px;
height: 100px;
background-color: red;
position: absolute;
left: 50%;
margin-left: -100px;
}
<div class='father'>
<div class="center">
</div>
</div>
若想要垂直也居中,则需要center中添加:
top: 50%;
margin-top: -50px;
定位+transform
- 父元素:相对定位
- 子元素:相对/绝对 定位 都可以
- 子元素
left:50%
,左边界到父元素的中间 - 子元素
transform: translateX(-50%);
,向左移动自己的一半,使得自己的中心对准父元素的中心 - 不需要知道子元素宽度
.father {
position: relative;
height: 500px;
width: 500px;
background-color: blue;
}
.center {
position: relative;
left: 50%;
width: 200px;
height: 200px;
background-color: red;
transform: translateX(-50%);
}
<div class='father'>
<div class="center">
</div>
</div>
text-align: center;
指定元素文本的水平居中。是行内元素。
text-align: center;
.parent {
text-align: center;
}
<div class='parent'>
<span>123</span>
</div>
margin: 0 auto;
margin: 0 auto;
- 要定宽,不定宽的话宽为
width:100%
- 块级元素
<div class='box'>是块级元素居中,块级元素内的不居中,想让这行文字也居中要用text-align</div>
.box {
background: skyblue;
width: 200px;
height: 200px;
margin: 0 auto;
}
【前端】CSS水平居中的6种方法_karshey的博客-CSDN博客
垂直居中(7种方法)
line-height
- 适用于单行的行内元素
- 设置line-height与height相等
绝对定位+margin:auto
- 子绝父相
- top、left、right、bottom都是0
- margin:auto
flex
display:flex
align-content:center
绝对定位+margin:负值
- 子绝父相
- 子元素top:50%:上边缘在父元素垂直居中的位置
- margin-top:子元素高度的一半(负数):将子元素中间移动到父元素居中的位置
定位+transform
- 父元素:相对定位
- 子元素:相对/绝对 定位 都可以
- 子元素
top:50%
,左边界到父元素的中间 - 子元素
transform: translateY(-50%);
,向左移动自己的一半,使得自己的中心对准父元素的中心 - 不需要知道子元素高度
vertical-align:middle
vertical-align 属性设置元素的垂直对齐方式。该属性定义行内元素的基线相对于该元素所在行的基线的垂直对齐。
因此,如果我要让box在wrapper里面垂直居中,我可以在wrapper的div里面加一个div 空 标签,把它的高度设为100%,宽度设置为0,再给它设置vertical-align:middle
,同样的给box一个vertical-align:middle
样式,那么box就可以在div里面垂直居中了。
.wrapper {
width: 500px;
height: 500px;
background-color: pink;
}
.box {
width: 100px;
height: 100px;
background-color: deepskyblue;
display: inline-block;
vertical-align: middle;
}
.help {
width: 0;
height: 100%;
display: inline-block;
vertical-align: middle;
}
<div class="wrapper">
<div class="box"></div>
<div class="help"></div>
</div>
利用vertical-align:middle垂直居中 - 简书 (jianshu.com)
display:table-cell
- 要垂直居中的元素的父元素设置
display:table-cell
和vertical-align:middle
- 默认情况下,图片,按钮,文字和单元格都可以用vertical-align属性
- 实现单行多行的文本垂直居中
body {
background: #ccc;
}
p {
display: table-cell;
vertical-align: middle;
background-color: pink;
width: 500px;
height: 200px;
}
<div>
<p>
hello world <br />
hello world <br />
hello world <br />
hello world
</p>
</div>
也可以加上display:table
,详情见:display:table-cell实现水平垂直居中 - 前端大兵 - 博客园 (cnblogs.com)
display:table和display:table-cell实现单行,多行文本垂直居中_喜欢文学的程序员的博客-CSDN博客
思维导图