上一期我整理介绍了grid布局方式,若是想看的同窗,能够直接点击此文章:
Grid布局css
这期我把flex布局方式笔记也整理出来了,内容是我本身在根据别人视频学习过程当中整理的资料。html
目前不少css的框架都使用Flexbox做为基础。浏览器大部分也都兼容。前端
接下来直接看代码演示,咱们先准备一个素材,准备5个div元素,定义为 ABCDE。由于div默认状况下display是block块级元素,因此默认状况下会独占一行。因此咱们获得以下图的排版。这就是咱们准备的素材。segmentfault
<div class="box A">A</div> <div class="box B">B</div> <div class="box C">C</div> <div class="box D">D</div> <div class="box E">E</div>
html { font-size: 12px; } .box { width: 60px; height: 60px; background-color: #eee; text-align: center; line-height: 60px; border-radius: 4px; box-shadow: 0 1px 3px rgba(0, 0, 0, .18); font-size: 2rem; } .A { background-color: #6dd98f; } .B { background-color: #0c7899; } .C { background-color: #961375; } .D { background-color: #bb7e38; } .E { background-color: #cfec9f; }
Flex布局方式主要就分为2个角色,Flex Container和Flex Items,也就是父容器和子项目。咱们先来改写素材。浏览器
<div class="flex-container"> <div class="box A">A</div> <div class="box B">B</div> <div class="box C">C</div> <div class="box D">D</div> <div class="box E">E</div> </div>
将四个div元素外部包括一个flex-container父容器,而且设置flex-container的display为flex。那么咱们便获得了以下图的布局。框架
.flex-container { display: flex; background-color: #2B34F5; }
这里父容器就是flex-container元素,而里面五个div则即是flex items子项目。布局
flex-direction这个属性是定义父容器中子项目,即flex items的排序方向。学习
flex-direction的默认值通常为 row,便是横向排序。flex
若是你改为:spa
flex-direction: column;
这时候即是纵向排序。
另外还有如下排序方式:
flex-direction: row-reverse; //横向倒转排序。
以下图:
flex-direction: column-reverse; //纵向倒转排序。
以下图:
这里有一个比较重要的知识点:主轴(main-axis)和交叉轴(cross-axis)。当flex属性不一样时候,主轴和交叉轴不一样。这个知识点须要和justify-content和align-items结合起来使用,下面咱们先来介绍justify-content和align-items这2个知识点。
flex-direction属性 | 主轴(main-axis) | 交叉轴(cross-axis) |
---|---|---|
row | row | column |
column | column | row |
justify-content是设置主轴的排序方向的。而align-items则是设置交叉轴的排序方向的。
咱们仍是看代码:
.flex-container { display: flex; background-color: #2B34F5; flex-direction: row; justify-content: center; }
咱们把flex-direction设置为row横向排序,这时候设置justify-content,即主轴方向居中,此时的主轴即是row,那么咱们能够获得以下图的效果:
可是当咱们把代码改成flex-direction: column时候,此时主轴便成了colunm,设置justify-content: center属性则不会获得水平方向的居中,以下图。
.flex-container { display: flex; background-color: #2B34F5; flex-direction: column; justify-content: center; }
此时,若是咱们要获得水平方向居中,则应该设置align-items:center,而不是justify-content: center。由于此时row水平方向是属于交叉轴。
.flex-container { display: flex; background-color: #2B34F5; flex-direction: column; justify-content: center; align-items: center; height: 500px; }
那咱们便把flex-container父容器高度设置大点,这时候主轴即是column,那么justify-content: center熟悉会让子元素垂直居中于父容器内,则align-items: center则会让子元素水平居中于父容器内。
从这个举例来看,是否是很好理解主轴和交叉轴概念。
另外,justify-content除了center外,还有其余各类属性
.flex-container { display: flex; background-color: #2B34F5; flex-direction: row; height: 500px; align-items: center; }
咱们把父容器恢复为flex-direction: row水平布局。
justify-content: flex-start; //沿着主轴起始方向排版布局
以下图:
justify-content: flex-end;//沿着主轴结束方向排版布局
以下图:
这里要记住一点:
设置flex-direction: row属性时候,justify-content属性设置为flex-start或flex-end,子元素都是由左至右排序。设置flex-direction: colunm属性时候,justify-content属性设置为flex-start或flex-end,子元素都是由上至下排序。即顺序都是ABCDE,不会是EDCBA。
flex-wrap便是会不会分行的意思。
<div class="flex-container"> <div class="box A">A</div> <div class="box B">B</div> <div class="box C">C</div> <div class="box D">D</div> <div class="box E">E</div> <div class="box A">A</div> <div class="box B">B</div> <div class="box C">C</div> <div class="box D">D</div> <div class="box E">E</div> <div class="box A">A</div> <div class="box B">B</div> <div class="box C">C</div> <div class="box D">D</div> <div class="box E">E</div> <div class="box A">A</div> <div class="box B">B</div> <div class="box C">C</div> <div class="box D">D</div> <div class="box E">E</div> </div>
咱们在父容器中加入多个子div,这时候咱们缩小浏览器的宽度。
.flex-container { display: flex; background-color: #2B34F5; flex-direction: row; justify-content: flex-start; align-items: center; height: 500px; }
这时候会发现,子div仍是会被压缩在水平方向一行,每一个子div宽度会被挤压。这是由于flex-wrap默认的属性值是nowrap,即不换行的意思,因此无论怎么添加子div,都只会在同一行。
若是咱们修改属性flex-wrap: wrap:
.flex-container { display: flex; background-color: #2B34F5; flex-direction: row; justify-content: flex-start; align-items: center; height: 500px; flex-wrap: wrap; }
这时候,超出宽度的子div便会被移到下一行中。这时候咱们再配合justify-content和align-items两个属性,就能获得不同效果,好比下面排版:
.flex-container { display: flex; background-color: #2B34F5; flex-direction: row; justify-content: center; align-items: center; height: 500px; flex-wrap: wrap; }
flex-flow是flex-direction和flex-wrap的组合起来的缩写。
.flex-container { display: flex; background-color: #2B34F5; flex-flow: row wrap; justify-content: center; align-items: center; height: 500px; }
flex-flow: row wrap; 在这里即是flex-direction:row,flex-wrap:wrap的缩写。这个能够根据我的习惯用此属性或者分2个属性编写。
align-content这个属性,是当flex-wrap设定为wrap的时候,便是有二行以及二行以上时候才会生效。直接看下图:
.flex-container { display: flex; background-color: #2B34F5; flex-flow: row wrap; justify-content: center; align-items: center; height: 500px; }
不设置align-content时候的以下图:
align-content: center;
align-content: center时候以下图:
align-content: space-between;
align-content: space-between时候以下图:
align-content: flex-start;
align-content: flex-start时候以下图:
由上面举例可知道,align-content是设定二行以二行以上时候,行与行之间的对齐方式。
order属性用于调整flex item的排序位置。咱们看如下参考案例:
.flex-container { display: flex; background-color: #2B34F5; flex-flow: row wrap; justify-content: center; align-items: center; height: 200px; width: 500px; }
<div class="flex-container"> <div class="box A">A</div> <div class="box B">B</div> <div class="box C">C</div> <div class="box D">D</div> <div class="box E">E</div> </div>
咱们仍是先设定父容器下5个子div,以flex布局方式,自动换行。
.B { background-color: #0c7899; order: 1; }
这时候咱们在B子DIV中加入属性值order:1,那么咱们会获得以下布局排版方式。
发现div B已经到了末尾,这是由于flex item的order默认值都是0,当B设定为1时候,由于flex布局容器会根据order数字以小到大排序,B便会移动至末尾排序。
.B { background-color: #0c7899; order: -1; }
若是咱们把B DIV的order设置为-1,则会排序到第一个。
order能够随意将个别flex item的位置进行改变。
align-self是用于覆盖flex container(父容器)的align-item的设置的
.flex-container { display: flex; background-color: #2B34F5; flex-flow: row wrap; justify-content: center; align-items: center; height: 200px; width: 500px; }
好比父容器中,咱们align-items的值设置了center居中。
.A { background-color: #6dd98f; align-self: flex-end; }
如以上代码,咱们修改DIV A的align-self属性为flex-end。那么咱们会获得以下图排版:
flex-basis是设置flex-item的主轴方向的大小的。
.flex-container { display: flex; background-color: #2B34F5; flex-flow: row wrap; justify-content: center; align-items: center; height: 200px; width: 500px; }
好比父容器中,咱们设置主轴为row,并能够换行。
.box { width: 60px; height: 60px; background-color: #eee; text-align: center; line-height: 60px; border-radius: 4px; box-shadow: 0 1px 3px rgba(0, 0, 0, .18); font-size: 2rem; flex-basis: 200px; }
在父容器的子div中添加flex-basis: 200px属性,此时此属性即表明子div的宽度为200px;以下图:
而若是咱们将主轴改成column。
.flex-container { display: flex; background-color: #2B34F5; flex-flow: column wrap; justify-content: center; align-items: center; height: 200px; width: 500px; }
此时flex-basis表明的是子div的高度,以下图:
要记住一点,在设置flex-basis后,原有的高度或者宽度都会失效,都会改成flex-basis的设定值去计算宽度或高度。若是flex-basis设置为0,若是没有overflow的设定,此时容器宽度或高度则取决于子div容器内内容的大小。以下图:
.flex-container { display: flex; background-color: #2B34F5; flex-flow: row wrap; justify-content: center; align-items: center; height: 200px; width: 500px; } .box { background-color: #eee; text-align: center; line-height: 60px; border-radius: 4px; box-shadow: 0 1px 3px rgba(0, 0, 0, .18); font-size: 2rem; flex-basis: 0; }
若是子容器再添加overflow属性,则以下面状况:
.box { overflow: hidden; background-color: #eee; text-align: center; line-height: 60px; border-radius: 4px; box-shadow: 0 1px 3px rgba(0, 0, 0, .18); font-size: 2rem; flex-basis: 0; }
overflow: hidden状况下,不会显示子div。
flex-grow是指当flex container的主轴方向有剩余空间的时候,flex item(容器子元素)沿主轴方向扩大的设置。
.flex-container { display: flex; background-color: #2B34F5; flex-flow: row wrap; justify-content: flex-start; align-items: center; height: 200px; width: 500px; } .box { width: 60px; height: 60px; background-color: #eee; text-align: center; line-height: 60px; border-radius: 4px; box-shadow: 0 1px 3px rgba(0, 0, 0, .18); font-size: 2rem; }
<div class="flex-container"> <div class="box A">A</div> <div class="box B">B</div> <div class="box C">C</div> <div class="box D">D</div> <div class="box E">E</div> </div>
.box { width: 60px; height: 60px; background-color: #eee; text-align: center; line-height: 60px; border-radius: 4px; box-shadow: 0 1px 3px rgba(0, 0, 0, .18); font-size: 2rem; flex-grow: 1; }
box属性中,咱们加入了 flex-grow: 1,这时候原先的排版便会变成如下结果:
子容器直接平均撑满整个父容器。这是由于五个div属性都是flex-grow: 1,那五个div便都是独占一份,会各自占剩余空间200px中的一份,即40px。
若是咱们不给每一个子div设定flex-grow,只设定其中A DIV元素
.box { width: 60px; height: 60px; background-color: #eee; text-align: center; line-height: 60px; border-radius: 4px; box-shadow: 0 1px 3px rgba(0, 0, 0, .18); font-size: 2rem; } .A { background-color: #6dd98f; flex-grow: 1; } .B { background-color: #0c7899; } .C { background-color: #961375; } .D { background-color: #bb7e38; } .E { background-color: #cfec9f; }
那么从上图排版,咱们会发现A DIV会独占剩余200px的全部空间。也就是A DIV宽度变成了60+200=260px;
而当主轴改成column时候,则是垂直方向A独占剩余空间。
.flex-container { display: flex; background-color: #2B34F5; flex-flow: column wrap; justify-content: flex-start; align-items: center; height: 500px; width: 500px; } .box { width: 60px; height: 60px; background-color: #eee; text-align: center; line-height: 60px; border-radius: 4px; box-shadow: 0 1px 3px rgba(0, 0, 0, .18); font-size: 2rem; } .A { background-color: #6dd98f; flex-grow: 1; } .B { background-color: #0c7899; } .C { background-color: #961375; } .D { background-color: #bb7e38; } .E { background-color: #cfec9f; }
flex-shrink则与flex-grow相反。是指当flex item子容器主轴方向的大小总和,超出父容器flex container的时候,flex item沿主轴方向如何缩小的设定。
.flex-container { display: flex; background-color: #2B34F5; flex-flow: row nowrap; justify-content: flex-start; align-items: center; height: 300px; width: 240px; } .box { width: 60px; height: 60px; background-color: #eee; text-align: center; line-height: 60px; border-radius: 4px; box-shadow: 0 1px 3px rgba(0, 0, 0, .18); font-size: 2rem; }
咱们将父容器宽度改成240px,主轴为row方向,不换行。每一个div设定为60px,那么理论上5个div应该有300px总和。可是如今父容器只有240px,少了60px。
咱们发现五个div还在同一行,可是宽度被缩减了。这是由于flex-shrink默认值都是1。
.box { width: 60px; height: 60px; background-color: #eee; text-align: center; line-height: 60px; border-radius: 4px; box-shadow: 0 1px 3px rgba(0, 0, 0, .18); font-size: 2rem; flex-shrink: 0; }
咱们如今每一个div设置flex-shrink: 0。这时候表明当主轴方向空间不足时候,不会去压缩子容器的宽度。那么咱们能够获得下图排版:
.A { background-color: #6dd98f; flex-shrink: 1; } .B { background-color: #0c7899; flex-shrink: 1; } .C { background-color: #961375; flex-shrink: 1; } .D { background-color: #bb7e38; flex-shrink: 1; } .E { background-color: #cfec9f; }
咱们在子DIV A、B、C、D中都加入属性值flex-shrink: 1,这表明ABCD四个DIV都各自分担一份被缩小的空间,也就是60/4=15px,那么ABCD四个div都会缩小为60-15=45px的宽度,而E由于flex-shrink:0,因此仍然会是60px的宽度。以下图排版:
flex的属性是flex-grow,flex-shrink和flex-basis组合起来的缩写。相似于父容器属性flex-flow,根据每一个人写法习惯不一样,能够拆分红三个属性分别写,也能够组合编写。这里很少作介绍。
前端学习过程要感谢B站的CodingStartup的Steven,不过他的讲解基本是粤语和视频,不少笔记我只能在看的过程本身整理,虽然直接我也从事程序开发,可是不少时候只知道要这么作,殊不知道为何要这么作,因此工做几年后从新回头巩固知识,以上是我在学习过程当中本身整理的学习笔记,但愿能够帮到你们。