Flex布局

上一期我整理介绍了grid布局方式,如果想看的同学,可以直接点击此文章:
Grid布局

这期我把flex布局方式笔记也整理出来了,内容是我自己在根据别人视频学习过程中整理的资料。

目前很多css的框架都使用Flexbox作为基础。浏览器大部分也都兼容。

接下来直接看代码演示,我们先准备一个素材,准备5个div元素,定义为 ABCDE。因为div默认情况下display是block块级元素,所以默认情况下会独占一行。所以我们得到如下图的排版。这就是我们准备的素材。

A
B
C
D
E
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布局_第1张图片

Flex Container和Flex Items

Flex布局方式主要就分为2个角色,Flex Container和Flex Items,也就是父容器和子项目。我们先来改写素材。

A
B
C
D
E

将四个div元素外部包括一个flex-container父容器,并且设置flex-container的display为flex。那么我们便得到了如下图的布局。

.flex-container {
    display: flex;
      background-color: #2B34F5;
}

Flex布局_第2张图片

这里父容器就是flex-container元素,而里面五个div则便是flex items子项目。

flex container中属性

flex-direction

flex-direction这个属性是定义父容器中子项目,即flex items的排序方向。

flex-direction的默认值一般为 row,即是横向排序。

如果你改成:

flex-direction: column;

这时候便是纵向排序。

Flex布局_第3张图片

另外还有以下排序方式:

flex-direction: row-reverse;  //横向倒转排序。

如下图:

image.png

flex-direction: column-reverse; //纵向倒转排序。

如下图:

Flex布局_第4张图片

这里有一个比较重要的知识点:主轴(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

justify-content是设置主轴的排序方向的。而align-items则是设置交叉轴的排序方向的。

我们还是看代码:

.flex-container {
    display: flex;
    background-color: #2B34F5;
    flex-direction: row;
    justify-content: center;
}

我们把flex-direction设置为row横向排序,这时候设置justify-content,即主轴方向居中,此时的主轴便是row,那么我们可以得到如下图的效果:

image.png

但是当我们把代码改为flex-direction: column时候,此时主轴便成了colunm,设置justify-content: center属性则不会得到水平方向的居中,如下图。

.flex-container {
    display: flex;
    background-color: #2B34F5;
    flex-direction: column;
    justify-content: center;
}

Flex布局_第5张图片

此时,如果我们要得到水平方向居中,则应该设置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则会让子元素水平居中于父容器内。

Flex布局_第6张图片

从这个举例来看,是不是很好理解主轴和交叉轴概念。

另外,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; //沿着主轴起始方向排版布局

如下图:

Flex布局_第7张图片

justify-content: flex-end;//沿着主轴结束方向排版布局

如下图:

Flex布局_第8张图片

这里要记住一点:

设置flex-direction: row属性时候,justify-content属性设置为flex-start或flex-end,子元素都是由左至右排序。设置flex-direction: colunm属性时候,justify-content属性设置为flex-start或flex-end,子元素都是由上至下排序。即顺序都是ABCDE,不会是EDCBA。

flex-wrap

flex-wrap即是会不会分行的意思。

A
B
C
D
E
A
B
C
D
E
A
B
C
D
E
A
B
C
D
E

我们在父容器中加入多个子div,这时候我们缩小浏览器的宽度。

.flex-container {
    display: flex;
    background-color: #2B34F5;
    flex-direction: row;
    justify-content: flex-start;
    align-items: center;
    height: 500px;
}

Flex布局_第9张图片

这时候会发现,子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;
}

Flex布局_第10张图片

这时候,超出宽度的子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布局_第11张图片

flex-flow

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

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时候的如下图:

Flex布局_第12张图片

align-content: center;

align-content: center时候如下图:

Flex布局_第13张图片

align-content: space-between;

align-content: space-between时候如下图:

Flex布局_第14张图片

align-content: flex-start;

align-content: flex-start时候如下图:

Flex布局_第15张图片

由上面举例可知道,align-content是设定二行以二行以上时候,行与行之间的对齐方式。

Flex Items中属性

order

order属性用于调整flex item的排序位置。我们看以下参考案例:

.flex-container {
    display: flex;
    background-color: #2B34F5;
    flex-flow: row wrap;
    justify-content: center;
    align-items: center;
    height: 200px;
    width: 500px;
}
A
B
C
D
E

我们还是先设定父容器下5个子div,以flex布局方式,自动换行。

.B {
    background-color: #0c7899;
    order: 1;
}

这时候我们在B子DIV中加入属性值order:1,那么我们会得到如下布局排版方式。

Flex布局_第16张图片

发现div B已经到了末尾,这是因为flex item的order默认值都是0,当B设定为1时候,因为flex布局容器会根据order数字以小到大排序,B便会移动至末尾排序。

.B {
    background-color: #0c7899;
    order: -1;
}

如果我们把B DIV的order设置为-1,则会排序到第一个。

Flex布局_第17张图片

order可以随意将个别flex item的位置进行改变。

align-self

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布局_第18张图片

flex-basis

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;如下图:

Flex布局_第19张图片

而如果我们将主轴改为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布局_第20张图片

要记住一点,在设置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;
}

Flex布局_第21张图片

如果子容器再添加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;
}

Flex布局_第22张图片

overflow: hidden情况下,不会显示子div。

flex-grow

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;
}
A
B
C
D
E

Flex布局_第23张图片

.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,这时候原先的排版便会变成以下结果:

Flex布局_第24张图片

子容器直接平均撑满整个父容器。这是因为五个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;
}

Flex布局_第25张图片

那么从上图排版,我们会发现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布局_第26张图片

flex-shrink

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。

Flex布局_第27张图片

我们发现五个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。这时候代表当主轴方向空间不足时候,不会去压缩子容器的宽度。那么我们可以得到下图排版:

Flex布局_第28张图片

.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布局_第29张图片

flex

flex的属性是flex-grow,flex-shrink和flex-basis组合起来的缩写。类似于父容器属性flex-flow,根据每个人写法习惯不同,可以拆分成三个属性分别写,也可以组合编写。这里不多做介绍。

前端学习过程要感谢B站的CodingStartup的Steven,不过他的讲解基本是粤语和视频,很多笔记我只能在看的过程自己整理,虽然直接我也从事程序开发,但是很多时候只知道要这么做,却不知道为什么要这么做,所以工作几年后重新回头巩固知识,以上是我在学习过程中自己整理的学习笔记,希望可以帮到大家。

你可能感兴趣的:(Flex布局)