flex布局和grid布局的详解(flex布局和grid布局的区别)
前言
刚进公司的前端实习生,同事让我从页面样式布局写起,当时UI给我提的需求是页面可以适应任何屏幕的分辨率,同时在屏幕大小变化的情况下,内容居中,到左右俩边的margin永远一样(就是内容永远居中,到右边的距离为margin-right:15px;那么到左边的距离也应该为margin-left:15px;)。当时觉得这个问题应该很简单,使用简单的CSS 样式就可以实现,给内容设置一个div,在div上添加margin:0 auto的样式,应该就可以实现,在多次修改之后UI大哥还是不满意,而且自己第一做有好多东西不懂,就去请教了当时进公司带我的师傅,师傅和我说可以试试flex布局。在研究flex布局的时候,又发现了grid布局,今天就把flex布局和grid布局一起整理一下。
在正文开始之前,先给大家说一下容器和项目的概念,之前再看容器和项目概念的时候,总是朦胧的认知,想着这不是一样的吗?后来真的弄明白之后才发现这个是不一样的。容器相当于一个盒子外面的包装--大箱子,项目是具体的内容--大箱子里面的小箱子,根据项目的属性给小箱子设置样式(小箱子在大箱子中的摆放顺序)
flex布局
基本概念
Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。任何一个容器都可以指定为 Flex 布局。采用 Flex 布局的元素,称为 Flex 容器,它的所有子元素自动成为容器成员,称为 Flex 项目。
注: 设为 Flex
布局以后,子元素的float
、clear
和vertical-align
属性将失效。
容器的属性
容器的属性一共有6
个,分别是:flex-direction、flex-warp、flex-flow、just-content、algin-items、align-content。
1. flex-direction:row(默认)——决定主轴的方向(项目排列的方向)
<style> /*这里的样式为接下来的所有页面的样式*/ .container{ width: 50%; display: flex; background-color: antiquewhite; box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1); } .box{ width: 100px; height: 100px; margin: 15px; background-color: coral; } </style> 复制代码
flex-direction:row/row-reverse(横向排列)
<body> <!--flex-direction:row--是默认排列方式,也是最常用的排列方式--> <h3>flex-direction:row--主轴为水平方向,从左向右排列</h3> <div class="container" style="flex-direction: row"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> </div> <h3>flex-direction:row-reverse--主轴为水平方向,从右向左排列</h3> <div class="container" style="flex-direction: row-reverse"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> </div> </body> 复制代码
flex-direction:column/column-reverse(纵向排列)
<body> <h3>flex-direction:column--主轴为垂直方向,从上向下排列</h3> <div class="container" style="flex-direction: column"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> </div> </body> 复制代码
<body> <h3>flex-direction:column-reverse----主轴为垂直方向,从下往上排列</h3> <div class="container" style="flex-direction: column-reverse"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> </div> </body> 复制代码
2.flex-warp:nowrap(默认)——当一条轴线上排列不下,怎么换行
<h3>flex-wrap: nowrap--不换行</h3> <div class="container" style="flex-direction: row;flex-wrap: nowrap"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> <div class="box">第四个</div> <div class="box">第五个</div> <div class="box">第六个</div> </div> 复制代码
<h3>flex-wrap: wrap--换行</h3> <div class="container" style="flex-direction: row;flex-wrap: wrap"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> <div class="box">第四个</div> <div class="box">第五个</div> <div class="box">第六个</div> </div> 复制代码
<div class="container" style="flex-direction: row;flex-wrap: wrap-reverse"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> <div class="box">第四个</div> <div class="box">第五个</div> <div class="box">第六个</div> </div> 复制代码
<h3>flex-direction:row-reverse 和 flex-wrap: wrap-reverse 的值的结合使用</h3> <div class="container" style="flex-direction: row-reverse;flex-wrap: wrap-reverse"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> <div class="box">第四个</div> <div class="box">第五个</div> <div class="box">第六个</div> </div> 复制代码
注: 以上演示的情况为主轴
方向为默认横向
时,所排列的样式。即:flex-direction:row;如果flex-direction:column主轴
为纵向
时,则排列方式就会如下图。
3.flex-flow:row nowrap(默认)
flex-flow: flex-direction flex-warp;
用于同时设置之前属性的值,下面以默认轴向为横向做演示。
flex-flow: row nowrap
<h3>flex-flow: row nowrap</h3> <div class="container" style="flex-flow: row nowrap"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> <div class="box">第四个</div> <div class="box">第五个</div> <div class="box">第六个</div> </div> 复制代码
flex-flow: row wrap
<h3>flex-flow: row wrap</h3> <div class="container" style="flex-flow: row wrap"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> <div class="box">第四个</div> <div class="box">第五个</div> <div class="box">第六个</div> </div> 复制代码
flex-flow: row wrap-reverse
<h3>flex-flow: row wrap-reverse</h3> <div class="container" style="flex-flow: row wrap-reverse"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> <div class="box">第四个</div> <div class="box">第五个</div> <div class="box">第六个</div> </div> 复制代码
4.justify-content: flex-start(默认)——设置主轴
上的排列方式
justify-content: flex-start
<h3>justify-content: flex-start</h3> <div class="container" style="justify-content: flex-start"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> </div> 复制代码
justify-content: flex-end
<h3>justify-content: flex-end</h3> <div class="container" style="justify-content: flex-end"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> </div> 复制代码
justify-content: center
<h3>justify-content:center</h3> <div class="container" style="justify-content: center"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> </div> 复制代码
之前我在前言中所遇到的问题,便是用这行代码样式解决的,到左右俩侧的距离永远一致。
justify-content: space-between
这个样式在排列布局的时候,会先将第一行和第二行的俩侧距离相等分配,之后在平均分配剩余的空间
<h3>两端对齐justify-content: space-between</h3> <div class="container" style="justify-content: space-between;flex-wrap: wrap"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> </div> <div class="container" style="justify-content: space-between;"> <div class="box">第一个</div> <div class="box">第二个</div> </div> 复制代码
justify-content: space-around
容器中的每个项目的左右边距相等,平均分配项目的左右边距。
<h3>justify-content: space-around:平均分配剩余空间</h3> <div class="container" style="justify-content: space-around;flex-wrap: wrap"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> <div class="box">第四个</div> <div class="box">第五个</div> <div class="box">第六个</div> <div class="box">第七个</div> </div> 复制代码
补充: 当主轴为column时,必需设置高度;
<style> .container{ width: 50%; background-color: antiquewhite; box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1); display: flex; flex-direction: row; } .main{ width: 50%; height:600px;/*如果不设置样式,则justify-content: center;就不起作用*/ background-color: antiquewhite; box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1); display: flex; flex-direction: column; } .box{ width: 100px; height: 100px; margin: 15px; background-color: coral; } </style> <body> <h3>justify-content: center</h3> <div style="justify-content: center;"> <div>第一个</div> <div>第二个</div> <div>第三个</div> </div> </body> 复制代码
5.algin-items:设置侧轴上的对齐方式(单行)
align-items: flex-start
<style> .container{ width: 50%; height: 300px; display: flex; background-color: antiquewhite; box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1); flex-direction: row; } .container1{ width: 50%; height: 600px; display: flex; background-color: antiquewhite; box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1); flex-direction: row; } .box{ width: 100px; height: 100px; margin: 15px; background-color: coral; } .box1{ width: 100px; height: 200px; margin: 15px; background-color: coral; } .box2{ width: 150px; height: auto; background-color: #47f816; } .box3{ width: 150px; background-color: #ee00ff; } </style> <body> <h3>align-items: flex-start</h3> <div class="container" style="align-items: flex-start"> <div class="box">第一个</div> <div class="box1">第二个</div> <div class="box">第三个</div> </div> </body> 复制代码
align-items: flex-end
<h3>align-items: flex-end</h3> <div class="container" style="align-items: flex-end"> <div class="box">第一个</div> <div class="box1">第二个</div> <div class="box">第三个</div> </div> 复制代码
align-items: center
<h3>align-items: center</h3> <div class="container" style="align-items: center"> <div class="box">第一个</div> <div class="box1">第二个</div> <div class="box">第三个</div> </div> 复制代码
align-items: baseline
<h3>align-items: baseline--以项目的第一行文字的对齐</h3> <div class="container" style="align-items: baseline;"> <div class="box">第一个 默认</div> <div class="box" style="align-self: flex-start">第二个 align-self: flex-start</div> <div class="box1" style="padding-top: 50px;">第三个 padding-top: 50px;</div> <div class="box" style="padding-top: 50px;"><p>第四个</p><p>padding-top: 50px;</p></div> </div> 复制代码
align-items: stretch
<h3>align-items: stretch</h3> <div class="container" style="align-items: stretch;"> <div class="box">第一个</div> <div class="box1">第二个</div> <div class="box">第三个</div> </div> 复制代码
<h3>align-items: stretch:不要设置高度</h3> <div class="container" style="align-items: stretch;"> <div class="box1">第一个</div> <div class="box2">height:auto</div> <div class="box3">没有设置高度</div> </div> 复制代码
6.align-content:设置侧轴上的对齐方式(多行)
align-content: flex-start
<style> .container{ width: 50%; height: 500px; background-color: antiquewhite; box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1); display: flex; flex-direction: row; flex-wrap: wrap; } .box{ width: 100px; height: 100px; margin: 15px; background-color: coral; } </style> <body> <h3>align-content: flex-start</h3> <div class="container" style="align-content: flex-start"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> <div class="box">第四个</div> <div class="box">第五个</div> <div class="box">第六个</div> <div class="box">第七个</div> <div class="box">第八个</div> </div> 复制代码
align-content: flex-end
<h3>align-content: flex-end</h3> <div class="container" style="align-content: flex-end"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> <div class="box">第四个</div> <div class="box">第五个</div> <div class="box">第六个</div> <div class="box">第七个</div> <div class="box">第八个</div> </div> 复制代码
align-content: center
<h3>align-content: center</h3> <div class="container" style="align-content: center"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> <div class="box">第四个</div> <div class="box">第五个</div> <div class="box">第六个</div> <div class="box">第七个</div> <div class="box">第八个</div> </div> 复制代码
align-content: space-around
<h3>align-content: space-around</h3> <div class="container" style="align-content: space-around"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> <div class="box">第四个</div> <div class="box">第五个</div> <div class="box">第六个</div> <div class="box">第七个</div> <div class="box">第八个</div> </div> 复制代码
align-content: space-between
<h3>align-content: space-between</h3> <div class="container" style="align-content: space-between"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> <div class="box">第四个</div> <div class="box">第五个</div> <div class="box">第六个</div> <div class="box">第七个</div> <div class="box">第八个</div> </div> 复制代码
align-content: space-evenly
<h3>align-content: space-evenly</h3> <div class="container" style="align-content: space-evenly"> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> <div class="box">第四个</div> <div class="box">第五个</div> <div class="box">第六个</div> <div class="box">第七个</div> <div class="box">第八个</div> </div> 复制代码
项目的属性
项目的属性是针对一个大的div中的具体的内容设置的元素(也就是给大箱子中的小箱子设置样式)。一共6
有个属性,分别是:order、flex-grow、flex-shrink、flex-basis、flex、align-self。
1. order
定义容器中项目的排列顺序,数值越小项目越靠前
.container{ width: 80%; height: 200px; display: flex; background-color: antiquewhite; box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1); flex-direction: row; } .box{ width: 100px; height: 100px; margin: 15px; background-color: coral; } 复制代码
<div class="container" style=""> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> <div class="box">第四个</div> <div class="box">第五个</div> </div> <h3>order:5--4--3--2--1</h3> <div class="container" > <div class="box" style="order: 5">第一个</div> <div class="box" style="order: 4">第二个</div> <div class="box" style="order: 3">第三个</div> <div class="box" style="order: 2">第四个</div> <div class="box" style="order: 1">第五个</div> </div> <h3>order:2 和 4 交换--只对添加的order的item 做排练顺序</h3> <div class="container" > <div class="box" >第一个</div> <div class="box" style="order: 2">第二个</div> <div class="box" >第三个</div> <div class="box" style="order: 4">第四个</div> <div class="box" >第五个</div> </div> 复制代码
补充: 当有俩个order的值相等时,按自己本身的值排列。如下:
<div class="container" > <!--这里有使俩个box 的order的值为3,style="order: 3--> <div class="box" style="order: 3">第一个</div> <div class="box" style="order: 3">第二个</div> <div class="box" style="order: 2">第三个</div> <div class="box" style="order: 4">第四个</div> <div class="box" style="order: 1">第五个</div> </div> 复制代码
2. flex-grow
属性定义项目存在剩余空间时的放大比例,默认值是flex-grow: 0。即使当宽度固定,子项目也会被放大。
<style> .container{ width: 50%; height: 200px; display: flex; background-color: antiquewhite; box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1); flex-direction: row; } .box{ width: 100px; height: 100px; margin: 15px; background-color: coral; } </style> 复制代码
<h3>默认</h3> <div class="container" style=""> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> </div> <h3>flex-grow: 2</h3> <div class="container" style=""> <div class="box">第一个</div> <div class="box" style="flex-grow: 2">第二个</div> <div class="box">第三个</div> </div> <h3>flex-grow: 0.5</h3> <div class="container" style=""> <div class="box">第一个</div> <div class="box" style="flex-grow: 0.5">第二个</div> <div class="box">第三个</div> </div> 复制代码
3. flex-shrink
项目的缩小比例,默认为flex-shrink: 1,当实际的项目大小超过容器所规定的大小时(容器空间不足时),项目就会自动缩小自己的宽度或者高度。
.container{ width: 50%; height: 200px; display: flex; background-color: antiquewhite; box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1); flex-direction: row; } .box{ width: 100px; height: 100px; margin: 15px; background-color: coral; } 复制代码
<h3>默认</h3> <div class="container" style=""> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> <div class="box">第四个</div> <div class="box">第五个</div> </div> <h3>2和4 的 flex-shrink: 0</h3> <div class="container" style=""> <div class="box">第一个</div> <div class="box" style="flex-shrink: 0">第二个</div> <div class="box">第三个</div> <div class="box" style="flex-shrink: 0">第四个</div> <div class="box">第五个</div> </div> 复制代码
4. flex-basis
在分配多余的空间之前,根据项目占据的主轴空间去计算在主轴上是否有多余的空间。默认值flex-basis: | auto; 即,项目本身的大小,我们设置项目元素的width的大小。
.container{ width: 100%; display: flex; background-color: antiquewhite; box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1); flex-direction: row; } .box{ width: 100px; height: 100px; margin: 15px; background-color: coral; } .box1{ height: 100px; margin: 15px; background-color: coral; } 复制代码
<h3>默认</h3> <div class="container" style=""> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> <div class="box">第四个</div> </div> <h3>设置auto 或者固定的像数值</h3> <div class="container" style=""> <div class="box" style="flex-basis: auto">第一个</div> <div class="box1" style="flex-basis: 300px;">flex-basis: 300px;</div> <div class="box">第三个</div> <div class="box" style="flex-basis: 500px;">设置宽度的基础上又设置了flex-basis: 500px;</div> </div> 复制代码
5. flex
flex-grow + flex-shrink + flex-basis = flex。定义子项目分配剩余空间,用flex来表述占多少份。
.container{ width: 50%; height: 200px; display: flex; background-color: antiquewhite; box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1);; } .box{ width: 100px; height: 100px; margin: 15px; background-color: coral; } 复制代码
flex:0 1 auto; 也可以写成
flex:1
<h3>flex:默认值 0 1 auto--不放大,会缩小</h3> <div class="container" style=""> <div class="box">第一个</div> <div class="box">第二个</div> <div class="box">第三个</div> </div> 复制代码
flex: 1 1 auto;也可以写成
flex: auto
<h3>flex:auto(1 1 auto)--等分放大缩小</h3> <div class="container" > <div class="box">第一个</div> <div class="box" style="flex:auto">第二个</div> <div class="box">第三个</div> </div> 复制代码
flex: 0 0 auto;
flex:none
<h3>flex:none(0 0 auto)--不放大不缩小</h3> <div class="container" > <div class="box">第一个</div> <div class="box" style="flex:none">第二个</div> <div class="box">第三个</div> </div> 复制代码
flex:1 0 auto;
<h3>flex:1 0 auto---会放大,不会缩小</h3> <div class="container" > <div class="box">第一个</div> <div class="box" style="flex:1 0 auto">第二个</div> <div class="box">第三个</div> </div> 复制代码
6. align-self
默认值为align-self:auto,继承父元素设置的align-items的值。控制子项目在侧轴的对其方式。
.container{ width: 50%; height: 400px; display: flex; background-color: antiquewhite; box-shadow: 0px 2px 2px 0px rgba(9, 2, 4, 0.1); align-items: center; } .box{ width: 100px; height: 100px; margin: 15px; background-color: coral; } .box1{ width: 100px; height: 200px; background-color: coral; } 复制代码
<h3>父容器设置的值为--align-items: center;</h3> <div class="container" style=""> <div class="box">第一个</div> <div class="box1" >第二个 </div> <div class="box" style="align-self: auto">第三个 align-self: auto</div> <div class="box" style="align-self: flex-end">第四个设置末端对齐align-self: flex-end</div> <div class="box" style="align-self: flex-start">第五个设置顶部对齐 align-self: flex-start</div> </div> 复制代码
最后
flex是一维布局 ,grid是二维布局;也就是说grid布局可以更好的操作行和列。flex布局和grid布局是现在的主流的两种布局方式。
项目演示获取代码地址
本来是想写grid布局的,但是感觉flex布局写的内容太多了,就临时打算把grid布局写在下一篇的更新文章中。。。。。。。。。
作者:striving
链接:https://juejin.cn/post/7031050931206619172