1. BFC到底是什么
BFC为 ‘块级格式化上下文’,简单理解为一个独立的空间,里面的元素不会影响到外界的布局。
1.触发BFC的条件
- position:absolute / fixed
- display:flex / inline-block / table-cell
- overflow: hidden 2.BFC解决了什么问题
- 高度塌陷
<div className="center">
<div>
<img src={img1} />
<p>图片1</p>
</div>
<div>
<img src={img2} />
<p>图片2</p>
</div>
<div>
<img src={img3} />
<p>图片3</p>
</div>
<div>
<img src={img4} />
<p>图片4</p>
</div>
</div>
.center {
padding: 15px 17px 20px;
div {
width: 25%;
float: left;
}
img {
display: block;
margin: 0 auto 10px;
padding: 10px;
border: 1px solid #00d39a;
border-radius: 30px;
}
p {
font-size: 12px;
text-align: center;
color: #535353;
}
}
效果:
如图 看到 父级元素center 的高度仅为 padding-top + padding-bottom 的高度
解决方案 只需要 父级元素 center 添加 overflow:hidden 即可
修改后的效果

- 两栏布局
<div className="m">
<div className="left">左侧导航区</div>
<div className="right">右侧自适应取</div>
</div>
.m{
overflow: hidden;
.left{
float: left;
padding:20px;
background:#00d39a;
}
.right{
background:#fd7964;
padding:30px;
}
}
效果:
如图 左侧浮动的导航区 覆盖右侧的自适应区
解决方案 .right 添加 display:flex;
修改后的效果

- 边距重叠
<div className="m">
<div className="left"></div>
<div className="right"></div>
</div>
.m{
overflow: hidden;
.left{
width:40px;
height:40px;
margin:10px;
background:#00d39a;
}
.right{
width:40px;
height:40px;
background:#fd7964;
margin:10px;
}
}
效果:

如图 每个盒子的边距为10px 所以上下两个盒子的间距因为为20px 但效果只有10px 明显的边距重叠了 解决方案 每个盒子渲染成独立的空间互不影响 .left 和 .right 都添加 float:left
2.垂直水平居中
垂直水平居中在面试中很常见,列举一些常用方案并说明应用场景,方案越多越加分哦 其中包括两类垂直水平居中问题 固定宽高/未知宽高
<div className="out">
<div className="in"></div>
</div>
#方案1 负margin (固定宽高)
.out{
width: 60px;
height:60px;
background:#00d39a;
position:relative;
}
.in{
width:30px;
height:30px;
background:#fd7964;
position:absolute;
left: 50%;
top:50%;
margin-top:-15px;
margin-left:-15px;
}
#方案2 transform (固定宽高/未知高度)
.out{
width: 60px;
height:60px;
background:#00d39a;
position:relative;
}
.in{
width:30px;
height:30px;
background:#fd7964;
position:absolute;
left: 50%;
top:50%;
transform: translate(-50%, -50%);
}
#方案3 定位 + 上下左右0 (固定宽高/未知高度)
.out{
width: 60px;
height:60px;
background:#00d39a;
position:relative;
}
.in{
width:30px;
height:30px;
background:#fd7964;
position:absolute;
top: 0;
right:0;
bottom:0;
left:0;
}
#方案4 flex (固定宽高/未知高度)
.out{
width: 60px;
height:60px;
background:#00d39a;
display: flex;
align-items: center; //垂直方向
justify-content: center; //水平方向
}
.in{
width:30px;
height:30px;
background:#fd7964;
}
#方案5 table-cell 子元素需要设置为行内元素 (固定宽高/未知高度)
.out{
width: 60px;
height:60px;
background:#00d39a;
display: table-cell;
text-align: center;
vertical-align: middle;
}
.in{
width:30px;
height:30px;
background:#fd7964;
display: inline-block;
}
3. 关于flex布局
在flex布局之前 我们通常用 浮动 定位来做布局 比如上一题提到的垂直水平居中的问题 利用浮动和定位有多种解决方案,弊端是需要清楚的理解定位和脱离文档流概念非常不方便,flex 非常简便的处理了这些问题。
阮一峰的 Flex 布局教程 非常详细建议多看多理解
常问的面试题: flex:1 是什么意思?
flex布局中的子容器属性中有三个属性 flex-grow : 定义项目的放大比例 默认为0 即存在剩余空间也不放大 flex-shrink: 定义项目的缩小比例 默认为1 即空间不够项目缩小 flex-basis: 定义在分配多余空间前,项目占据的主轴空间 默认值为auto 即项目本来大小
还有一个flex属性 是以上三个属性的缩写 默认值为 0 1 auto 它有两个快捷值 auto (1 1 auto)放大缩小 none(0 0 auto)不放大不缩小
举个例子
<div className="m">
<div className="item">第一段落的内容比较长</div>
<div className="item">第二段</div>
<div className="item">第三段</div>
</div>
.m{
width:200px;
margin:30px;
display: flex;
border: 1px solid #00d39a;
.item{
border: 1px solid #fd7964;
flex:1;
}
flex:1 如图所示为平均分配

flex:auto 根据内容分配

flex:none 为不放大不缩小 如图子元素内容超出父元素

flex:0 最小内容宽度

经典的圣杯布局 可以用flex很简单的实现
4.关于移动端1px问题
在实际开发中会有很多边框设置成1px 但效果总是看起来比1px粗一些,从而达不到UI预期 解决方案1:
<div className="m">
<div className="item">第一段落的内容比较长</div>
<div className="item">第二段</div>
<div className="item">第三段</div>
</div>
.m{
width:200px;
margin:30px;
display: flex;
border: 1px solid transparent;
border-image: linear-gradient(to bottom, transparent 50%, #00d39a 50%) 0 0 100%/1px 0;
padding:10px;
.item{
border: 1px solid #fd7964;
flex:1;
}
}

如图 红色边框为正常1px 绿色边框为细1px
方案2:阴影 box-shadow: 0px 0.5px 0px 0px #00d39a;
方案3:相对定位 + 伪类
position: relative;
:before{
content: '';
position: absolute;
left:0;
bottom: 0;
width: 100%;
height: 1px;
background: #ee2c2c;
transform: scaleY(0.5);
}
以上整理了几个常见问题,后续还会补充。