写到前面
做前端的都知道,网页的布局是最麻烦的一件事了,虽然很多的事情都是很麻烦的,但是布局绝对是里面相对比较烦人的一件事了,之前的常见的布局方式有盒子模型,就是依赖于display+position+float的办法。但是一般的布局用这些还是没有问题的,也不是说特别的麻烦,但是如果是处理垂直居中的时候就会很麻烦,那么为了解决这个问题,2009年伟大的W3C提出了一种新的布局福方式-Flex布局。那么今天我们就简单的看看这个布局是怎么回事!
Flex是Flexible Box的缩写,意为”弹性布局”,其实就是为了将盒子模型变得更加的灵活。
他的兼容性还是很强的,目前主流的浏览器都是支持的:(明人不说暗话,图是偷的)
首先说一下怎么使用,我知道很多的文章都介绍了,说的也很明白,其实我写这篇文章的意义在于自己可以更加清楚的知道每一个属性的用法,毕竟别人的东西不可以按照我的思路来,另一个意义在于和我想的一样的人可以看到这篇文章....
指定Flex布局直接这样写:
.box{
display: flex;
}
如果是行内元素使用也是可以的:
.box{
display: inline-flex;
}
Webkit内核的浏览器,需要加上前缀:
.box{
display: -webkit-flex; /* Safari */
display: flex;
}
到这里可能有人骂了,你这和菜鸟教程不是一样的吗?还有必要写吗?是的,是一样的,但是开头本来就这样的啊,我也是很无奈...
下面我们分别说
要想明白Flex怎么回事,首先要明白几个概念,第一叫做容器,第二叫做项目,第三个叫做主轴,最后一个是交叉轴
首先我们说一下什么是容器?
说人话就是最外面的那个div或者别的元素,被设置了Flex属性的就是容器
例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
/* 这里的webkit是为了支持谷歌的内核 */
.box{
width: 90rem;
height: 50rem;
border: 5px solid darkcyan;
display: -webkit-flex;
}
</style>
</head>
<body>
<!-- 这里面的所有的元素都叫做flex项目,即flex布局里面的成员 -->
<div class="box">
</div>
</body>
</html>
这里的div就是一个容器,
什么是项目?
容器里面的每一个小的元素就是项目,例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
/* 这里的webkit是为了支持谷歌的内核 */
.box{
width: 90rem;
height: 50rem;
border: 5px solid darkcyan;
display: -webkit-flex;
}
.item{
width: 50px;
height: 50px;
border: 5px solid darkcyan;
margin-left: 1rem;
margin-top: 1rem;
}
</style>
</head>
<body>
<!-- 这里面的所有的元素都叫做flex项目,即flex布局里面的成员 -->
<div class="box">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</body>
</html>
这里的class=item的就是项目,这里有三个项目。
什么是主轴?
主轴是相对于容器来说的,容器默认的是有两根轴的,水平的叫做主轴,主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end
什么是交叉轴?
交叉轴也是相对于容器来说的,垂直的叫做交叉轴,交叉轴的开始位置叫做cross start,结束位置叫做cross end。
PS:单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。
如图:(图也是偷的,我画的不好看,怕恶心到你们)
下面我们就开始说属性,前面我们说了,Flex主要是容器和项目这两个玩意儿,那么属性也是分开的,分别是容器的属性和项目的属性,我们分开说,首先是容器的属性:
容器的属性包括了六个,(也就是写到.box这个css里面的属性)分别是:
这里不明白没事,下面我们一个一个的说!
容器属性1:Flex-firection这个属性决定的是项目的排列方向!
例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
/* 这里的webkit是为了支持谷歌的内核 */
.box{
width: 100%;
height: 100%;
border: 1px solid darkcyan;
display: -webkit-flex;
flex-direction: row;/* 这个属性叫做布局的方向,属性默认的是从左往右排列,row-reverse叫做横向反着排列,column 是从上往下的排列,column-reverse是从下往上的排列 */
}
.item{
width: 150px;
height: 80px;
border: 3px solid red;
margin-left: 2rem;
margin-top: 2rem;
}
</style>
</head>
<body>
<!-- 这里面的所有的元素都叫做flex项目,即flex布局里面的成员 -->
<div class="box">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
</body>
</html>
他的四个值很简单:
上面我写的例子直接复制全部运行就行,然后将值换掉就可以看到不同的效果了!
容器属性2:flex-wrap这个属性就比较实用了,这个是设置是不是换行的。
例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
/* 这里的webkit是为了支持谷歌的内核 */
.box{
width: 100%;
height: 100%;
border: 1px solid darkcyan;
display: -webkit-flex;
flex-wrap: wrap;/* 这个是怎么换行的问题,默认的是不换行,那么warp的是直接换行,warp-reverse叫做换行,但是是往上挤,不是直接默认往下来*/
}
.item{
width: 150px;
height: 80px;
border: 3px solid red;
margin-left: 2rem;
margin-top: 2rem;
}
</style>
</head>
<body>
<!-- 这里面的所有的元素都叫做flex项目,即flex布局里面的成员 -->
<div class="box">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
</body>
</html>
PS:我知道这里的div的项目可以用js遍历写出来,但是为了那些不知道怎么遍历写的人我觉得还是这样写比较接地气,虽然很麻烦。想知道怎么写的,可以翻翻我之前写的文章,里面像这样的重复的代码,我一般是js写的。
他的四个值是这样的:
nowrap : 不换行
wrap : 换行
wrap-reverse:换行,但是第一行被挤到下面
容器属性3:flex-flow
这个属性就比较有意思了,这个是前面两个属性的默认值的总结,也就是说如果你前面两个全是默认值的话,那么可以直接写这一个就行了,他的默认值是row和mowrap,也就是从左向右排列,不换行。所以一般不准备改变值得情况下是推荐直接写这个的。
容器属性4:justify-content这个属性是定义了主轴的对齐方式,说人话就是一行项目做左对齐还是右对齐还是两端对齐等。
例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
/* 这里的webkit是为了支持谷歌的内核 */
.box{
width: 100%;
height: 100%;
border: 1px solid darkcyan;
display: -webkit-flex;
justify-content: flex-start;/* 这个叫做主轴的对齐方式,默认的是左对齐,也就是flex-start */
}
.item{
width: 150px;
height: 80px;
border: 3px solid red;
margin-left: 2rem;
margin-top: 2rem;
}
</style>
</head>
<body>
<!-- 这里面的所有的元素都叫做flex项目,即flex布局里面的成员 -->
<div class="box">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</body>
</html>
他的值是:
ps:这里值得一提的是具体的方向其实是和主轴的方向有直接关系的。
容器属性5:align-items这个属性呢是定义了在交叉轴上的对齐方式
例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
/* 这里的webkit是为了支持谷歌的内核 */
.box{
width: 100%;
height: 100%;
border: 1px solid darkcyan;
display: -webkit-flex;
display: flex;
align-items: stretch;
}
.item{
width: 150px;
height: 80px;
border: 3px solid red;
margin-left: 2rem;
margin-top: 2rem;
}
</style>
</head>
<body>
<!-- 这里面的所有的元素都叫做flex项目,即flex布局里面的成员 -->
<div class="box">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
</body>
</html>
他的值是:
PS:这里还是一样的,具体的对齐方式其实是和交叉轴的对齐方式有直接关系的。
容器属性6:align-content 这个属性定义了多跟轴线的对齐方式,什么是多根轴线呢?很简单,前面不是说了吗?可以直接定义换行,不知道你们还记不记得,换行以后就是一个新的轴线。
例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
/* 这里的webkit是为了支持谷歌的内核 */
.box{
width: 100%;
height: 100%;
border: 1px solid darkcyan;
display: -webkit-flex;
display: flex;
align-items: stretch;
}
.item{
width: 150px;
height: 80px;
border: 3px solid red;
margin-left: 2rem;
margin-top: 2rem;
}
</style>
</head>
<body>
<!-- 这里面的所有的元素都叫做flex项目,即flex布局里面的成员 -->
<div class="box">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
</body>
</html>
他的值是:
下面介绍的属性就不是容器的属性了,叫做项目的属性,也就是容器里面的每一个小的块的属性。
其实看到这里你们发现我是和菜鸟教程的过程是一样的,其实我写这篇文章也就是参考的菜鸟教程的结构写的,只是为了每一个都用代码写一下,看看有没有什么存在的问题,然后将思路捋一下。
项目属性1:order这个是定义了项目的排列顺序,这个是很有用的,我个人觉得,很多的时候我们写div的时候,会有写到好几个了,然后 发现位置不对,这个时候又要重新布局,如果使用这个就完全不用的,直接改一下order的值就行了,具体怎么使用呢?例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
/* 这里的webkit是为了支持谷歌的内核 */
.box{
width: 100%;
height: 100%;
border: 1px solid darkcyan;
display: -webkit-flex;
display: flex;
flex-direction: row;/* 这个属性叫做布局的方向,属性默认的是从左往右排列,row-reverse叫做横向反着排列,column 是从上往下的排列,column-reverse是从下往上的排列 */
flex-wrap: wrap;/* 这个是怎么换行的问题,默认的是不换行,那么warp的是直接换行,warp-reverse叫做换行,但是是往上挤,不是直接默认往下来*/
justify-content: space-between;/* 这个叫做主轴的对齐方式,默认的是左对齐,也就是flex-start */
align-items: baseline;
align-content: center;
}
.item{
width: 150px;
height: 80px;
border: 3px solid red;
margin-left: 2rem;
margin-top: 2rem;
order: 0;
}
.item1{
width: 150px;
height: 80px;
border: 3px solid red;
margin-left: 2rem;
margin-top: 2rem;
order: 2;
}
.item2{
width: 150px;
height: 80px;
border: 3px solid red;
margin-left: 2rem;
margin-top: 2rem;
order: 1;
}
.item3{
width: 150px;
height: 80px;
border: 3px solid red;
margin-left: 2rem;
margin-top: 2rem;
order: 3;
}
</style>
</head>
<body>
<!-- 这里面的所有的元素都叫做flex项目,即flex布局里面的成员 -->
<div class="box">
<div class="item">1</div>
<div class="item1">2</div>
<div class="item2">3</div>
<div class="item3">4</div>
</div>
</body>
</html>
还是一样直接运行就行了
项目属性2:flex-grow这个定义了项目的方法比例,默认的是0,即不放大,这个是怎么算的呢?也很简单,如果大家都是一个1的话,那么大家都是等比的分, 那么如果都是0,即使有空间也不放大,如果一个是2倍的是1,那么这个2的将是别的1的双倍。
例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
/* 这里的webkit是为了支持谷歌的内核 */
.box{
width: 100%;
height: 100%;
border: 1px solid darkcyan;
display: -webkit-flex;
display: flex;
flex-direction: row;/* 这个属性叫做布局的方向,属性默认的是从左往右排列,row-reverse叫做横向反着排列,column 是从上往下的排列,column-reverse是从下往上的排列 */
flex-wrap: wrap;/* 这个是怎么换行的问题,默认的是不换行,那么warp的是直接换行,warp-reverse叫做换行,但是是往上挤,不是直接默认往下来*/
justify-content: space-between;/* 这个叫做主轴的对齐方式,默认的是左对齐,也就是flex-start */
align-items: baseline;
align-content: center;
}
.item{
width: 150px;
height: 80px;
border: 3px solid red;
margin-left: 2rem;
margin-top: 2rem;
order: 0;
flex-grow: 0;
}
.item1{
width: 150px;
height: 80px;
border: 3px solid red;
margin-left: 2rem;
margin-top: 2rem;
order: 2;
flex-grow: 1;
}
.item2{
width: 150px;
height: 80px;
border: 3px solid red;
margin-left: 2rem;
margin-top: 2rem;
order: 1;
flex-grow: 2;
}
.item3{
width: 150px;
height: 80px;
border: 3px solid red;
margin-left: 2rem;
margin-top: 2rem;
order: 3;
flex-grow: 4;
}
</style>
</head>
<body>
<!-- 这里面的所有的元素都叫做flex项目,即flex布局里面的成员 -->
<div class="box">
<div class="item">1</div>
<div class="item1">2</div>
<div class="item2">3</div>
<div class="item3">4</div>
</div>
</body>
</html>
项目属性3:flex-shrink这个属性定义了项目的缩小比例,但是这个默认的是1,也就是说,如果空间不够的时候回出现等比缩小的处理,这个简直是神技啊,不是吗。之前的时候我们一般是写@media处理一下这个,但是现在使用这个的话,只需要一个属性就搞定了,简直是神技了。
ps:如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。负值对该属性无效。
例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
/* 这里的webkit是为了支持谷歌的内核 */
.box{
width: 100%;
height: 100%;
border: 1px solid darkcyan;
display: -webkit-flex;
display: flex;
flex-direction: row;/* 这个属性叫做布局的方向,属性默认的是从左往右排列,row-reverse叫做横向反着排列,column 是从上往下的排列,column-reverse是从下往上的排列 */
justify-content: space-between;/* 这个叫做主轴的对齐方式,默认的是左对齐,也就是flex-start */
align-items: baseline;
align-content: center;
}
.item{
width: 150px;
height: 80px;
border: 3px solid red;
margin-left: 2rem;
margin-top: 2rem;
order: 0;
flex-shrink: 1;
}
.item1{
width: 150px;
height: 80px;
border: 3px solid red;
margin-left: 2rem;
margin-top: 2rem;
order: 0;
flex-shrink: 0;
}
/* 这个其实是可以直接看到的,如果不换行的话,那么他的默认的就是直接等比缩小的 */
</style>
</head>
<body>
<!-- 这里面的所有的元素都叫做flex项目,即flex布局里面的成员 -->
<div class="box">
<div class="item">1</div>
<div class="item">1</div>
<div class="item">1</div>
<div class="item">1</div>
<div class="item">1</div>
<div class="item">1</div>
<div class="item">1</div>
<div class="item">1</div>
<div class="item">1</div>
<div class="item">1</div>
<div class="item">1</div>
<div class="item">1</div>
<div class="item">1</div>
<div class="item">1</div>
<div class="item">1</div>
<div class="item">1</div>
<div class="item1">1</div>
</div>
</body>
</html>
项目属性4: flex-basiss这个属性定义在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。
其实吧这个属性我是没看出来怎么回事,也没有试出来,谁比较明白这个,可以私信我一下,谢谢了。
项目属性5:flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。
和之前的那个容器属性是一样的,如果你的属性是flex-grow, flex-shrink 和 flex-basis的默认值,那么你是可以直接写这个的。
例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
/* 这里的webkit是为了支持谷歌的内核 */
.box{
width: 100%;
height: 100%;
border: 1px solid darkcyan;
display: -webkit-flex;
display: flex;
flex-direction: row;/* 这个属性叫做布局的方向,属性默认的是从左往右排列,row-reverse叫做横向反着排列,column 是从上往下的排列,column-reverse是从下往上的排列 */
justify-content: space-between;/* 这个叫做主轴的对齐方式,默认的是左对齐,也就是flex-start */
align-items: baseline;
align-content: center;
}
.item{
width: 150px;
height: 80px;
border: 3px solid red;
margin-left: 2rem;
margin-top: 2rem;
order: 0;
flex: auto;
}
/* 这个其实是可以直接看到的,如果不换行的话,那么他的默认的就是直接等比缩小的 */
</style>
</head>
<body>
<!-- 这里面的所有的元素都叫做flex项目,即flex布局里面的成员 -->
<div class="box">
<div class="item">1</div>
<div class="item">1</div>
<div class="item">1</div>
<div class="item">1</div>
</div>
</body>
</html>
项目属性6:align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
/* 这里的webkit是为了支持谷歌的内核 */
.box{
width: 40rem;
height: 20rem;
border: 1px solid darkcyan;
display: -webkit-flex;
display: flex;
flex-direction: row;/* 这个属性叫做布局的方向,属性默认的是从左往右排列,row-reverse叫做横向反着排列,column 是从上往下的排列,column-reverse是从下往上的排列 */
justify-content: space-between;/* 这个叫做主轴的对齐方式,默认的是左对齐,也就是flex-start */
align-items: baseline;
align-content: center;
}
.item{
width: 150px;
height: 80px;
border: 3px solid red;
margin-left: 2rem;
margin-top: 2rem;
order: 0;
flex: none;
flex-shrink:1;
}
.item1{
width: 150px;
height: 80px;
border: 3px solid red;
margin-left: 2rem;
margin-top: 2rem;
order: 0;
flex: none;
align-self: flex-end;
}
</style>
</head>
<body>
<!-- 这里面的所有的元素都叫做flex项目,即flex布局里面的成员 -->
<div class="box">
<div class="item">1</div>
<div class="item">1</div>
<div class="item">1</div>
<div class="item1">1</div>
</div>
</body>
</html>
ok,到这里其实就没有了,新的flex布局还是非常的好玩和有趣的,喜欢的朋友可以一起交流,一起进步!