前言
在做项目的时候写页面我通常都是使用 flex 来布局的,flex 不仅能方便控制元素的水平、垂直方向的布局,更能在父容器内弹性分布。我也看到过 grid 也很强大,那么 Flex 和 Grid 在布局方面谁更胜一筹呢?
flex
Flex(Flexible Box),也称为弹性布局 ,可以简便、完整、响应式地实现各种页面布局。它是2009年由W3C
提出的新的布局方案,可以响应式地实现各种页面布局,目前Flex
技术已经得到了所有浏览器的支持。
使用
在使用 flex 的时候需要将一个容器设置为 flex 容器,而这个容器下的子元素就成为了 item,就可以控制 item 元素的位置和排序方式,并且子元素的 float 、clear 和 vertical-align 属性将失效。
html
<style>
.container {
display: flex;
border: 1px solid red;
padding: 10px;
}
.item {
width: 100px;
height: 100px;
background-color: red;
margin-left: 10px;
}
</style>
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>

从上图来看原本 div 是块级元素,应该是独占一行的,然而给父元素设置了 flex ,子元素全都变成了像行内元素。
原因是父元素设置了 display: flex;
,默认主轴的方向是 x 轴 也就是行 flex-direction: row;
,导致子元素按 x 轴排列;还可以设置为 flex-direction: column;
,按 y 轴排列。
设置了 flex 不仅可以控制子元素的排列,还形成了 BFC。
BFC
BFC (Block Formatting Context), 名为 "块级格式化上下文"。BFC 是一个完全独立的空间(一块独立的渲染区域),让空间里的子元素不会影响到外面的布局。
BFC 常见的场景是 解决 margin重叠、清除浮动、高度塌陷等问题。
Flex 的容器属性
- flex-direction 控制 item 项目排列方向
- flex-wrap 控制项目是否换行
- justify-content 定义了项目在主轴上的对齐方式
- align-items 定义项目在交叉轴上如何对齐
总结
总的来说 Flex 布局有着 主轴 和 交叉轴 的控制,item 子元素依照着这两个轴进行位置排列的,所以 Flex 弹性布局也可以称为轴线布局。
从维度 角度上看,Flex 布局是 一维布局。
grid
Grid 称为网格布局,是微软于 2010 年提出的一种新的布局方式,于2016 年提交了该布局的草案。经过近几年发展,兼容性越来越好。
使用
grid-template-columns
定义每一列的列宽, 其中的repeat
表示重复次数grid-template-rows
定义每一行的行高
css
.container {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: 100px 100px 100px;
}

Grid 的容器属性
- gap 设置 行间距 列间距
- grid-auto-flow 设置放置顺序,默认是 row 按行放置,column 先列放置
- place-items 单元格内容放置位置,为 (align-items justify-items) 的简写
- place-content 容器里面单元格的位置放置, 为 (align-content justify-content) 的简写
- grid-template-areas 指定单元格命名
css
grid-template-areas: 'a b c'
'd e f'
'g h i';
还有给 item 元素设置的属性
- grid-column-start , grid-column-end , grid-row-start , grid-row-end ,这四个属性可以指定 item 的边框定位在哪根网格线上
css
.item-5 {
background-color: rgb(51, 230, 90);
grid-column-start: span 2; // span 关键字为跨越几个单元格
grid-row-start: 1;
grid-row-end: 4;
}

- grid-area 指定 item 放在哪一个区域,区域名由容器 grid-template-areas 属性控制。也可以当作上面四个属性的简写
css
.item-5 {
// <row-start> / <column-start> / <row-end> / <column-end>;
grid-area: 1 / 1 / 3 / 3;
}
- place-self 设置单元格内容位置放置,是 (align-self justify-self) 的简写
总结
总的来说 Grid 布局将容器划分成行和列,并产生单元格,然后将 item 子元素放置在对应的单元格里,可以精确的控制各个单元来进行布局,可以看作是二维布局,所以 Grid 布局远比 Flex 布局强大,但是属性较多、相对复杂。
最后
- 布局复杂和控制性上,Grid 强于 Flex
- 在兼容性上,Flex 优于 Grid
- Flex 的属性相对于 Grid 较为简单,容易使用
因此我们应该根据项目实际情况灵活去选择 Flex 或者是 Grid,它们两者各有各的优点。