在开始学前端的时候,搞懂了css的盒子模型,布局的话基本上通过margin、padding、border、float来调试div的样式和位置,感觉到万分繁杂。但是但是那个时候还不知道有css3。有了display:flex(弹性布局、自动布局)就可以摆脱调试margin和padding的烦恼了,总之我是这么认为的,如有些博主取名的标题一样,确实是前端布局神器。本文是根据一些博主的文章加上自身的理解写的,以加强印象。
提醒一下,本文中不涉及交叉轴的概念,对于我来说那玩意儿就是混淆视听的,并非必要理解的,在本文中需要用非主流意识去理解自动布局(弹性布局)的方式,本文涉及大量样式图片和样式代码,介意慎入。
2020年4月3日修改内容如下:文章结构,大部分图例
2020年4月4日修改内容如下:部分图例,属性描述
2020年4月6日修改内容如下:新增部分用例图解析,部分属性及其值的阐述
2020年7月18日2020年7月19日修改内容如下:审核了全部内容,将图片大部分修改,实例重做,效果图重新渲染。使之更容易理解
目录
编写与运行环境声明:
重要参考链接:
参考资料网站:
理解要点:
本文实例基础代码
先决:排列方向概念
正文开始
一、flex-direction属性:自定义主轴方向
1、row(默认值):行内元素排列(主轴)方向往右
2、row-reverse:行内元素排列(主轴)方向往左
3、column:主轴方向往下
4、column-reverse:主轴方向往上
5*、读者朋友可能会遇到的困惑
二、flex-wrap属性:定义换行方式
1.nowarp:不换行(默认值)
2.wrap:向下换行
3.wrap-reverse:镜像换行(反向换行)
三:flex-flow:flex-direction与flex-wrap的复合属性
四、justify-content属性:定义一行内,元素(item)的水平对齐方式
1.{start,flex-start}:沿着一行的排列起点方向水平对齐
2.{end,flex-end}一行内,元素沿着排列方向水平对齐
3.center:元素往一行的中点线水平对齐
4.space-between:子元素沿一行的两端对齐
5.space-around:将剩余的空间均分至元素两侧
6.space-evenly:将一行上的剩余空间均分到所有间隙上
7 .参考链接
五、align-items属性:设置元素再在一行内的垂直对齐方式
1.stretch:元素的高度充满行高(默认值)
2.flex-start:子元素行内垂直向上对齐(置顶)
3.center:子元素行内垂直居中
4.flex-end:子元素行内垂直向下对齐
5.baseline:以元素内第一行文本水平线作为主轴线对齐元素
六、align-content属性:定义行之间的对齐方式
1.flex-start:各行垂直向上对齐
2.flex-end:各个行向下对齐
3.center:各行垂直居中
4.space-between:各行上下两端对齐
5.space-around:各行分散对齐
由于本文较长,涉及内容和实例样式较多,又出于对时效性的考虑,有必要先说明下环境与运行条件及环境
链接:https://pan.baidu.com/s/1HVS4w5MnxDGRfubRm4n4Yg
提取码:7x87文件大小:30kb
前端布局神器display:flex - 青春时光 - 博客园
css自动布局第二弹:元素样式--链接
css参考手册
以下是在容器设置了display:flex的条件下,对容器内元素的排列对齐方式,进行配置的简介
以下是对父元素设置了display:flex的条件下,子元素自身在父元素中的特殊样式设置。由于篇幅原因,第二弹介绍以下内容
基础代码与样式配置:
1
2
3
4
5
关于动态盒子(自动盒子、弹性盒子)的有关博文中,无不提及主轴概念,本文同样要提及这个布局中的主轴,首先这个主轴是逻辑上的主轴,并非可见的,唯有去理解这个主轴是什么。
一句话来简单概括下:容器内,每一行元素的排列方向
给容器定义了了display:flex后,每一行的默认块元素的排列方向自左向右排列,且容器宽度不够的时候不会换行。在容器不另外给添加附加属性的情况下,容器内的所有子元素,都将变成从左往右排列,这是默认的排列方式。
现在我们可以基于上文中基础代码样式中,给容器样式加上display:flex配置,查看效果图。
前方省略
....
#body {
margin: 20px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex; /*新加的样式配置*/
}
....
后方省略
注意:上面的div之所以变成了高度占满容器的样子,是因为设置为flex布局以后,align-item的属性默认值为stretch,所以才会看到这个自动扩充现象。关于align-item在后面第五节才会介绍。
当然,(主轴)除了默认的自左向右的排列方式以外,也可以自定义的排列方向,此时就需要使用flex-direction属性配置。例如我想要每一行(主轴)按照自右向左的排列方式:
前方省略
...
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row-reverse;/*设置主轴(行内)排列方向自右向左*/
}
...
后方省略
另外还有自下而上,自上而下的两种配置。
该属性可供选择的值一共有四个:{row,row-reverse,column,column-reverse}
通过在而介绍主轴概念阶段时。现在希望你能理解到主轴方向分别有四个,分别是上、下、左、右,以上四个值就代表这四个方向。当然,在自定义容器主轴方向之前,首先要将容器的display:flex样式配置好,这样我们就能愉快的设置主轴方向啦!
容器内一行上的元素排列自左向右,就算没有配置这个附属属性,只是配置了display:flex,默认的显示也是这样子的,默认会给容器加上flex-direction:row这个配置。
以上省略
...
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row;/*配置排列方向自左向右*/
}
...
以下省略
表示容器一行内子元素自右往左排列,也就是主轴方向自右向左。配置及效果如下
以上省略
....
#body {
margin: 20px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row-reverse;/*配置排列方向自右向左*/
}
....
以下省略
flex-direction的第三个属性表示设置其内部子元素排列由主轴方向自上而下,图例:
以上省略
....
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: column;/*一行元素自上而下排列,也就是配置主轴自上而下*/
}
....
以下省略
flex-direction的第四种主轴方向是自下而上的,取值column-reverse,
以上省略
....
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: column-reverse;
}
....
以下省略
在前文的介绍flex-direction中,如果读者朋友在根据本文配置容器的同时,还对其子元素样式做了一些修改的话,可能会遇到一种情况,那就是在设置了子元素的宽度的情况下、且所有的子元素宽度之和大于容器宽度,而子元素排列不会撑破容器到达容器外面,而且子元素固有的宽度也变小了,这点是非常有意思的。我会在下文第二节的第1小节末尾说明,请继续看下文。
flex-wrap取值范围:{nowrap,wrap,wrap-reverse}
当容器的一行内,元素宽度之和大于容器宽度的时候,应该怎么办?换行排列?还是不换行,继续在一行排列?
这个时候flex-wrap出现就是为了声明:当一行中,元素宽度之和大于容器宽度时,是否应该换行,以及怎样换行。
这个属性表示容器内元素不换行,这是默认值。就算不在css样式中显式的配置也会有一样的作用。
前方省略
...
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row; /*容器(父元素)一行内的元素排列方向
(或者叫主轴方向)改为自左向右*/
flex-wrap: nowrap; /*因为wrap是默认值,
所以这个配置可有可无,
效果都一样*/
}
[class^=item] {
width: 100px; /*容器(父元素)所有子元素的宽度改为100px*/
background-color: red;
border-style: outset;
border-width: 3px;
border-color: black;
text-align: center;
font-family: myfont;
font-size: 60px;
}
...
后方省略
通过以上的配置按照我们常见思路来看,元素的总宽度已经超过了容器宽度了,但是实际效果图出来却是下图:
通过浏览器的开发者工具可以看到,容器的宽度还是400px,但是容器内的元素(item)的宽度却变小了。
以上这个现象跟flex-shrink配置属性有关系,这个是定义容器的元素按照比例缩小,触发条件为剩余空间不足时,也就是说一行的宽度容不下所有的元素时,会发生自我缩小,默认值为1,在这里你只需要在这里理解为:一行内的所有元素按照等比缩小知道直到容器宽度能容下所有元素位置就行了。这个是我在文章第二弹才会涉及的内容,所以在这里不做过多介绍。
现在只是了解上述现象即可,没有理解到也没有关系,因为这里直接提出,也是不妥当的,此时为了说明一些读者朋友可能会遇到的情况而做一个简单的demo演示与说明,并不会影响接下来的阅读。
flex-wrap取值为wrap时,就是定义沿着主轴方向排列元素时,当第一行的宽度不够容纳所有的元素宽度之和时,会往下新创建一行排列元素。新的主轴线会按照第一行元素的排列规则,继续排列主轴线排剩下的元素,如果还排不下,那么就再创建新的行继续排,以此类推。
以上省略
...
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row;
flex-wrap: wrap;/*这里将容器设置为可以换行*/
}
...
以下省略
一句话概括就是flex-flow有俩值,前后分别为flex-direction 和 flex-wrap的值,格式如下
flex-flow:
如果我们没有写这个,那么默认就会取flex-direction和 flex-wrap的值,如果没有自定义flex-direction与flex-wrap的值,那么浏览器就会为我们自动配置
flex-flow: row nowrap
该属性的可取值:{start | flex-start , flex-end | end , center , space-between , space-around , space-evenly , stretch(默认)}
这个display:flex的附加属性,用于设定容器的子元素在一行中的水平对齐方式。介绍justify-content之前,假设flex-direction都是设置row,且flex-wrap都是设置的row,基础配置如下
以上省略
...
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
...
以下省略
其实这一组属性都是表示主轴线起点(主轴线方向的反方向)对齐,这两个属性是同一个意思。因为是默认值,所以就算justify-content的值不设置的情况下,浏览器样式解析器也会自动加上这个值。
以上省略
...
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: start; /*因为start|flex-start是默认值,
所以这一行有没有配置都会是一样的效果*/
}
...
以下省略
注意:本文撰写时,Google Chrome并不支持justify-content值为start、end的写法,但是Firefox支持
这一组值表示顺着主轴线方向的容器边框对齐
以上省略
...
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: end;/*这里设置为flex-end表示沿着排列方向对齐*/
}
...
以下省略
注意:本文撰写时,Google Chrome并不支持justify值为start、end的写法,但是Firefox支持
justify-content:center设置子元素在主轴线上居中,居中后的子元素之间没有间隙。
以上省略
...
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content:center;
}
...
以下省略
justify-content:space-between:设定主轴线上的各个子元素向主轴线两端对齐。就是将主轴线上排满元素后,将剩余的宽度均匀平分到各个元素之间的间隔上。注意,是各个元素之间的间隔,不包括元素与容器之间的间隔哦。
以上省略
....
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
}
....
以下省略
justify-content:space-around:将主轴线上排满元素后的剩余的主轴线宽度,平均划分到各元素的两边,注意是每个元素的两边。
解析图:
黄色区域是来自于主轴上没有被占用完的富余空间, 而被平分到各个元素两边了。4、5、6格子之间也是这样的
justify-content:space-envenly:将主轴线上的富余宽度均分到所有的间隙。这个间隙包括主轴线上元素和容器边框之间的间隙,子元素之间的间隙。
文档中虽然给了许多可能的值,但是好多都没有作用的
参考链接:justify-content - CSS(层叠样式表) | MDN
可取值:{stretch , flex-start|start|left , flex-end|end|right , center , baseline , frist baseline , last baseline}
display:flex的附加属性align-items用于设置主轴线上的元素垂直对齐方式。如果将justify-content,比作设置二维坐标轴上的x轴对齐方式的话,那么align-itmes就是用来设置元素在y轴上的对齐方式。
align-items:stretch在一行内,元素没有设置高度的情况下,会自动将元素的高度调整为行的高度。但是设置了高度的话,那么就会按照设定好的高度显示。
例如下面这个:
以上省略
...
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
align-item:stretch /*stretch为默认值,
所以即使没有配置这个样式,
你也能看到下图中的渲染样式*/
}
[class^=item] {
width: 100px;
background-color: red;
border-style: outset;
border-width: 3px;
border-color: black;
text-align: center;
font-family: myfont;
font-size: 60px;
}
/*这里新添加的样式配置*/
.item2 {
height: 100px;
}
...
以下省略
渲染图片显示的是,1、3、4、5都充满了行高,因为他们没有被设置高度,所以它的高度是等于行的高度的,但是我们在上面样式配置中给2号设置了行高:100px,所以它的和其他盒子不一样。
align-items:flex-start:用于设定行内向上对齐。当然这是基于水平对齐的基础之上向上对齐的哦,也就是说基于justify-content的基本位置,做元素的水平中点向上顶,达到行的顶部
配置如下:
以上省略
...
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: stretch;
align-items:flex-start; /*设置向上对齐*/
}
[class^=item] {
width: 100px;
background-color: red;
border-style: outset;
border-width: 3px;
border-color: black;
text-align: center;
font-family: myfont;
font-size: 60px;
}
.item1{
height: 200px; /*设置第一个盒子的高度为200像素*/
}
.item2 {
height: 100px; /*设置第二个盒子的高度为100像素*/
}
.item3{
height: 150px; /*设置第三个盒子的高度为150像素*/
}
...
以下省略
以上省略
...
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
align-items:center; /*行内的所有元素垂直居中*/
}
...
以下省略
配置:aligin-items:flex-end
align-items:baseline:表示以第一个元素的文本内容作为基本线对齐,也就是默认按照第一个元素中的,第一行文字为基本线;然后同一行内,其他元素内部的文字,也按照这个基本线向上对齐,也就是文字最顶部不会高于这个基本线。
以上省略
...
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
align-items:baseline; /*设置以第一个元素内的第一行文字为水平线*/
}
[class^=item] {
width: 100px;
background-color: red;
border-style: outset;
border-width: 3px;
border-color: black;
text-align: center;
font-family: myfont;
font-size: 60px;
}
.item1{
height: 200px;
margin-top: 20px; /*设置顶部外边距为20像素*/
padding-top: 20px; /*设置顶部内边距为20像素*/
}
.item2 {
height: 100px;
}
.item3{
height: 150px;
padding-top: 50px;/*设置内边距为50像素*/
}
.item5{
padding-top: 14px;
}
...
以下省略
通过以上配置,读者不知道发现没有,我的第三号元素,内边距已经大于第一号元素所设定的基本线位置,第一号元素的基本线,应该在第一行上高度像素位,减去一号盒子的外边距(20像素),再减去一号盒子的内边距(20像素),所以基准线应该在行的上边框像素位减去40个像素,才正确。但是第三号元素内边距却还是50像素,按道理应该已经超出容器了才对,但是这里使用弹性布局后,没有冲破容器,而是将基本线下调了10个像素,以保证容器内的元素不会冲破元素。
所以新的基本线应该在行高所在的基本线下调50个像素的位置。
可选值:{flex-start|start , flex-end|end , center , space-between , space-around , space-evenly , stretch}
值得区分的是:justify-content设定一行内、元素之间水平排列样式,而align-content属性是设定各行之间,在垂直方向上排列样式;align-items是对行内的元素,设定在当前行上的垂直对齐方式。
我们在介绍align-content的属性值前,先说明下,在本文开始的基础代码上,修改成以下内容:
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
align-items: center;
}
[class^=item] {
width: 100px;
background-color: red;
border-style: outset;
border-width: 3px;
border-color: black;
text-align: center;
font-family: myfont;
font-size: 60px;
}
.item1 {
height: 200px;
/*删除了margin-top:20px*/
padding-top: 20px;
}
.item2 {
height: 100px;
}
.item3 {
height: 150px;
padding-top: 50px;
}
.item5 {
padding-top: 14px;
}
以上省略
...
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
align-items: baseline;
align-content:flex-start/*新增各行垂直向容器顶部对齐的样式*/
}
...
以下省略
以上省略
...
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
align-items: baseline;
align-content:flex-end; /*配置各行向容器底部对齐*/
}
...
以下省略
以上省略
...
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
align-items: baseline;
align-content:center; /*各行按着容器高度中点线对齐,
也可以理解外将剩余空间均分至容器两端*/
}
...
以下省略
以上省略
...
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
align-items: baseline;
align-content:space-between;
}
...
以下省略
以上省略
...
#body {
margin: 250px auto;
width: 400px;
height: 400px;
border-style: inset;
border-width: 4px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
align-items: baseline;
align-content:space-around;/*将剩余的空白均分至行的上下两端*/
}
...
以下省略