这是我参与11月更文挑战的第一天,活动详情请查看:2021最后一次更文挑战
前言
刚进公司的前端实习生,同事让我从页面样式布局写起,当时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 class="main" style="justify-content: center;">
<div class="box">第一个</div>
<div class="box">第二个</div>
<div class="box">第三个</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布局写在下一篇的更新文章中。。。。。。。。。