哎呀吆博客

大前端爱好与探索者-Jerry

Flex弹性布局深入学习

CSS 0 评

Flex是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。任何一个容器都可以指定为Flex布局。使用时将元素的display属性设置为flex即可。注意,使用Flex布局以后,子元素的float,clear,vertical-align属性将失效。
flex布局
从上图可以看出,flex中的核心概念就是容器和轴,所有的属性都是围绕容器和轴来设置的。其中。容器分为父容器和子容器;轴分为主轴(main axis)和交叉轴(cross axis),主轴默认水平方向,方向向右,交叉轴为主轴顺时针旋转90度。
主轴开始的位置为main start,结束的位置为main end;交叉轴开始的位置为cross start,结束的位置为cross end。子元素占据主轴空间叫做main size,占据交叉轴空间叫做cross size
注:以下除非特殊说明,否则案例展示中的flex-direction都为默认值row

1 父容器

属性:

  • flex-direction
  • flex-wrap
  • flex-flow
  • justify-content
  • align-items
  • align-content

1.1 flex-direction

设置主轴方向,默认为水平方向。该属性常用的4个值:
row:主轴为水平方向,起点在左端
HTML结构:

<div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
</div>

CSS:

.container{
    display: flex;
    flex-direction: row;
    background: pink;
}  
.item{
    width: 50px;
    height: 50px;
    margin-right: 25px;
    background-color: skyblue;
    color: #fff;
    text-align: center;
    line-height: 50px;
}

row-reverse:主轴为水平方向,起点在右端

.container{
    ...
    flex-direction: row-reverse;
    ...
}    
...

column:主轴为垂直方向,起点在上沿

.container{
    display: flex;
    flex-direction: column;
    background: pink;
}
.item{
    width: 100%;
    height: 50px;
    margin-bottom: 25px;
    background: skyblue;
    text-align: center;
    color: #fff;
    line-height: 50px;
}

column-reverse:主轴为垂直方向,起点在下沿

.container{
    ...
    flex-direction: column-reverse;
    ...
}    
...

各个属性值对应的布局效果如下图:
flex-direction

1.2 flex-wrap

用来设置子容器在一行轴线排不下,该如何进行换行。
flex-wrap
该属性常用的3个值:
nowrap(默认):不换行
HTML结构:

<div class="container container">
    <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 class="item">11</div>
    <div class="item">12</div>
</div>

CSS:

.container{
    width: 100%;
    display: flex;
    flex-wrap: nowrap;
    background: pink;
}
.item{
    width: 100px;
    height: 100px;
    margin-right: 25px;
    background: skyblue;
    text-align: center;
    color: #fff;
    line-height: 100px;
}

wrap:换行,第一行在上方

.container{
    ...
    flex-wrap: wrap; /* 默认 */
    ...
}
.item{
    ...
    margin-right: 25px;
    margin-bottom: 15px;
    ...
}

wrap-reverse:换行,第一行在下方

.container{
    ...
    flex-wrap: wrap-reverse; /* 默认 */
    ...
}
.item{
    ...
}

各个属性值对应的布局效果如下图:
flex-wrap

1.3 flex-flow

flex-flow是flex-direction、flex-wrap两个属性的简写形式,默认值是row nowrap

1.4 justify-content

用于设置子容器在主轴上的对齐方式。该属性常用的5个值:
flex-start(默认):靠主轴开始的位置对齐
HTML结构:

<div class="container">
    <div class="item1 item">1</div>
    <div class="item2 item">2</div>
    <div class="item3 item">3</div>
</div>

CSS:

.container{
    width: 100%;
    display: flex;
    justify-content: flex-start;
    background: pink;
}
.item{
    height: 100px;
    margin-right: 15px;
    background: skyblue;
    text-align: center;
    line-height: 100px;
    color: #fff;
}
.item1{
    width: 300px;
}
.item2{
    width: 50px;
}
.item3{
    width: 150px;
}

flex-end:靠主轴结束的位置对齐

.container{
    ...
    justify-content: flex-end;
    ...
}
...

center:居中对齐

.container{
    ...
    justify-content: center;
    ...
}
...
.item1{
    width: 300px;
    margin-left: 0;
}
...

space-between:两端对齐,子容器间隔相等

.container{
    ...
    justify-content: space-between;
    ...
}
.item{
    height: 100px;
    background: skyblue;
    text-align: center;
    line-height: 100px;
    color: #fff;
}
...

space-around:子容器两端间距相等。所以两个子容器之间的距离要比子容器距离父容器的距离要大一倍

.container{
    ...
    justify-content: space-around;
    ...
}
.item{
    height: 100px;
    background: skyblue;
    text-align: center;
    line-height: 100px;
    color: #fff;
}
...

各个属性值对应的布局效果如下图:
justify-content

1.5 align-items

用于设置子容器在交叉轴上的对齐方式。该属性常用的5个值:
flex-start:靠交叉轴的起点对齐
HTML结构:

<div class="container">
    <div class="item1 item">item1</div>
    <div class="item2 item">item2</div>
    <div class="item3 item">item3</div>
    <div class="item4 item">item4</div>
</div>

CSS:

.container{
    width: 100%;
    height: 140px;
    display: flex;
    align-items: flex-start;
    background: pink;
}
.item{
    width: 100px;
    margin-right: 25px;
    background: skyblue;
    line-height: 30px;
    text-align: center;
    color: #fff;
}
.item1{
    height: 50px;
}
.item2{
    height: 100px;
}
.item3{
    height: 60px;
}
.item4{
    height: 75px;
}

flex-end:靠交叉轴的终点对齐

.container{
    ...
    align-items: flex-end;
    ...
}
...

center:交叉轴方向居中

.container{
    ...
    align-items: center;
    ...
}
...

baseline:以子容器中第一行文字的基线对齐
HTML结构:

<div class="container">
    <div class="item1 item"><p>item1</p></div>
    <div class="item2 item"><p style="font-size: 20px;">item2</p></div>
    <div class="item3 item"><p style="font-size: 24px">item3</p></div>
    <div class="item4 item"><p>item4</p></div>
</div>

CSS:

.container{
    width: 100%;
    height: 140px;
    display: flex;
    align-items: baseline;
    background: pink;
}
.item{
    width: 100px;
    margin-right: 25px;
    background: skyblue;
    text-align: center;
    color: #fff;
}
...

stretch(默认值):如果项目未设置高度或设置为auto,将占满整个容器的高度
各个属性值对应的布局效果如下图:
align-items

1.6 align-content

用于设置多根轴线的对齐方式。若父容器内只有一条轴线,那么该属性将失去作用。该属性常用的6个值:
flex-start:靠交叉轴的起点对齐
HTML结构:

<div class="container">
    <div class="item1 item">item1</div>
    <div class="item2 item">item2</div>
    <div class="item3 item">item3</div>
    <div class="item4 item">item4</div>
    <div class="item5 item">item5</div>
    <div class="item6 item">item6</div>
    <div class="item7 item">item7</div>
    <div class="item8 item">item8</div>
    <div class="item9 item">item9</div>
    <div class="item10 item">item10</div>
</div>

CSS:

.container {
    height: 200px;
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
    background: pink;
}

.item {
    height: 50px;
    margin: 10px 0 10px 25px;
    line-height: 50px;
    text-align: center;
    color: #fff;
    background: skyblue;
}

.item1 {
    width: 130px;
}

.item2 {
    width: 100px;
}

.item3 {
    width: 50px;
}

.item4 {
    width: 120px;
}

.item5 {
    width: 80px;
}

.item6 {
    width: 60px;
}

.item7 {
    width: 70px;
}

.item8 {
    width: 55px;
}

.item9 {
    width: 65px;
}

.item10 {
    width: 85px;
}

flex-end:靠交叉轴的终点对齐

.container {
    ...
    align-content: flex-end;
    ...
}

center:交叉轴方向居中

.container {
    ...
    align-content: center;
    ...
}

space-between:交叉轴方向两端对齐,轴线之间的间隔平均分布

.container {
    ...
    align-content: space-between;
    ...
}

space-around:交叉轴方向,每条轴线的两侧间隔大小都相等。因此,轴线之间的间隔要大于轴线与父容器之间的间隔

.container {
    ...
    align-content: space-around;
    ...
}

stretch(默认):轴线占满整个交叉轴

.container{
    height: 200px;
    display: flex;
    flex-wrap: stretch;
    background: pink;
}
.item{
    height: 50px;
    margin: 10px 0 10px 25px;
    ...
}
...

各个属性值对应的布局效果如下图:
align-content

2 子容器

属性:

  • order
  • flex-grow

  • flex-shrink

  • flex-basis

  • flex

  • align-self

order
用于设置子容器的排列顺序。数值越小,排列越靠前,默认为0。
HTML结构:

<p>flex-direction: row</p>
<div class="order-row-container container">
    <div class="item1 item">item1(order: 5)</div>
    <div class="item2 item">item2(order: 1)</div>
    <div class="item3 item">item3(order: 3)</div>
    <div class="item4 item">item4(order: 5)</div>
</div>
<p>flex-direction: column</p>
<div class="order-column-container container">
    <div class="item1 item">item1(order: 1)</div>
    <div class="item2 item">item2(order: 10)</div>
    <div class="item3 item">item3(order: 2)</div>
    <div class="item4 item">item4(order: -1)</div>
</div>

CSS:

.container{
    display: flex;
    background: pink;
}
.order-row-container{
    flex-direction: row;
}
.order-column-container{
    flex-direction: column;
    margin-top: 20px;
}
.item{
    height: 50px;
    line-height: 50px;
    text-align: center;
    color: #fff;
    background-color: skyblue;
}
.order-row-container .item{
    margin: 10px;
}
.order-column-container .item{
    margin: 10px;
}
.order-row-container .item1{
    order: 5;
}
.order-row-container .item2{
    order: 1;
}
.order-row-container .item3{
    order: 3;
}
.order-row-container .item4{
    order: 5;
}
.order-column-container .item1{
    order: 1;
}
.order-column-container .item2{
    order: 10;
}
.order-column-container .item3{
    order: 2;
}
.order-column-container .item4{
    order: -1;
}

布局效果如图所示:
order

flex-grow
用于设置子容器在父容器的占比,默认为0。
HTML结构:

<p>1:1:1</p>
<div class="flex-grow-container container">
    <div class="item1 item">item1</div>
    <div class="item2 item">item2</div>
    <div class="item3 item">item3</div>
</div>
<p>1:2:1</p>
<div class="flex-grow-container2 container">
    <div class="item1 item">item1</div>
    <div class="item2 item">item2</div>
    <div class="item3 item">item3</div>
</div>

CSS:

.container{
    display: flex;
    background-color: pink;
}
.item{
    flex-grow: 1;
    height: 50px;
    margin: 10px;
    line-height: 50px;
    text-align: center;
    color: #fff;
    background-color: skyblue;
}
.flex-grow-container2 .item1{
    flex-grow: 1;
}
.flex-grow-container2 .item2{
    flex-grow: 2;
}
.flex-grow-container2 .item3{
    flex-grow: 1;
}

布局效果如图所示:
flex-grow

flex-shrink
用于设置子容器在父容器空间不足的情况下是否允许缩放,1是允许缩放,0是不允许,负值无效,默认为1。
HTML结构:

<div class="flex-shrink-container container">
    <div class="item1 item">item1</div>
    <div class="item2 item">item2</div>
    <div class="item3 item">item3</div>
    <div class="item4 item">item4<br />(flex-shrink: 0)</div>
    <div class="item5 item">item5</div>
    <div class="item6 item">item6</div>
    <div class="item7 item">item7</div>
    <div class="item8 item">item8</div>
</div>

CSS:

 .container{
     display: flex;
     background-color: pink;
}
.item{
    width: 120px;
    height: 100px;
    margin: 10px;
    line-height: 50px;
    text-align: center;
    color: #fff;
    background-color: skyblue;
}
.flex-shrink-container .item4{
    flex-shrink: 0;
}

布局效果如图所示:
flex-shrink

flex-basis
用于设置在分配多余空间之前,子容器占据的主轴空间。浏览器根据这个属性计算主轴是否有多余的空间。默认值为auto。

flex
flex-growflex-shrinkflex-basis三个属性的简写形式,默认值为0 1 auto。常用的两个快捷值:
flex: auto(1 1 auto)
flex: none(0 0 auto)

align-self
用于设置当前子容器覆盖align-items属性从而表现出与其他子容器不一样的对齐方式。默认值为auto,表示同其他子容器相同,若没有父元素,相当于设置了stretch。该属性常用的6个值:
auto
flex-start
flex-end
center
baseline
stretch
HTML结构:

<div class="align-self-container container">
    <div class="item1 item">item1()</div>
    <div class="item2 item">item2</div>
    <div class="item3 item">item3<br />(align-self: flex-start)</div>
    <div class="item4 item">item4</div>
</div>

CSS:

.container{
    display: flex;
    background-color: pink;
}
.align-self-container{
    align-items: flex-start;
    height: 300px;
}
.item{
    width: 150px;
    margin: 10px;
    line-height: 50px;
    text-align: center;
    color: #fff;
    background-color: skyblue;
}
.align-self-container .item1{
    height: 150px;
}
.align-self-container .item2{
    height: 240px;
}
.align-self-container .item3{
    height: 180px;
    align-self: flex-end;
}
.align-self-container .item4{
    height: 200px;
}

使用布局效果如图所示:
align-self

写此篇博文仅仅是为了给自己的学习留下记录,所以大都是陈述,总结偏少,水平着实有限,继续努力吧!

发表评论

电子邮件地址不会被公开。 必填项已用*标注