06-移动web之flex布局

一、基本概念

  • flex布局又叫伸缩布局 、弹性布局 、伸缩盒布局 、弹性盒布局
  • Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。
  • 任何一个容器都可以指定为 Flex 布局。
  • 当我们为父盒子设为 flex 布局以后,子元素的 float、clear 和 vertical-align 属性将失效。
  • flex布局就是通过给父盒子添加flex属性,来控制子盒子的位置和排列方式。

1.flex的特点

  • 设置了display: flex;的元素称之为父项。
  • 父项里面的亲儿子元素称之为子项。
  • 父项中有一条默认水平向右的轴称之为主轴。
  • 父项有一条垂直与主轴且默认垂直向下的轴称之为侧轴。
  • 设置了flex,里面的子项不论是什么元素显示模式,都拥有了设置宽高的权利。

二、flex中的父项属性

1.改变主轴方向(flex-direction)

            /* 改变主轴方向 */
            /* 主轴垂直向下,当主轴占据侧轴位置时,侧轴会转换到主轴位置上,且方向时钟水平向右 */
            /* flex-direction: column; */

            /* 主轴垂直向上,侧轴水平向右 */
            /* flex-direction: column-reverse; */

            /* 默认值,主轴水平向左,侧轴垂直向下 */
            /* flex-direction: row; */

            /* 主轴水平向右,侧轴垂直向下 */
            flex-direction: row-reverse;

UTOOLS1586526465936.png
UTOOLS1586526495474.png

注意

  • 只能控制主轴的方向
  • 主轴和侧轴与x,y轴完全不是一个东西。
  • 主轴控制的实际上是控制流的方向。
  • 主轴为垂直方向时,占据了侧轴的位置,此时侧轴就会转换为主轴方向,方向始终是水平向右。

2.改变子项在主轴上的排列顺序(justify-content)

            /* 默认从起点到终点排列 */
            /* justify-content: flex-start; */

            /* 从终点到起点排列 */
            /* justify-content: flex-end; */

            /* 居中对齐 */
            justify-content: center;

            /* 先固定;两端,剩下的元素平分剩下的空间 */
            /* justify-content: space-between; */

            /* 每个子项两侧的间隔相等。所以,子项之间的间隔比子项与边框的间隔大一倍 */
            /* justify-content: space-around; */

            /* 均衡分布,子项分分父相空间 */
            justify-content: space-evenly;

UTOOLS1586526988198.png
UTOOLS1586527026471.png

3.设置侧轴上的子项排列方式(align-items 单行)

         /* 从起点到终点 */
            /* align-items: flex-start; */
            /* 从终点到起点 */
            /* align-items: flex-end; */
            /* 居中对齐 */
            /* align-items: center; */

            /* 拉伸,默认值
            当侧轴处置垂直向下时,如果子项未设置高度或设为auto,将占满整个容器的高度。
            当侧轴水平向右时 如果子项未设置宽度或设为auto,将占满整个容器的宽度*/
            align-items: stretch;

UTOOLS1586527869412.png
UTOOLS1586528042673.png
默认值为stretch

4.换行(flex-wrap)

默认子元素是不换行的,如果装不开,会缩小子元素的宽度,强制一行排列。

            /* 默认不换行,强行缩小子元素使其在一行上显示 */
            flex-wrap: nowrap;

            /* 换行 */
            /* flex-wrap: wrap; */

            /* 反向换行 */
            /* flex-wrap: wrap-reverse; */

UTOOLS1586528661047.png
注意

  • 必须所有子项的宽度相加大于父相宽度才能换行,否则即使设置换行也无效。
  • 换行时候为什么行之间间距那么大?
    原因:由于侧轴的默认属性是stretch,有多少行就将父元素拉伸为多少份,每一份中的每一行在起点对齐,每一份多出每一行的高度就是各行之间的空隙。
    解决:1.设置align-content:flex-atart;
    2.将盒子高度去掉或者auto,即可铺满整个父项。

4.设置侧轴上子项的排列方式(align-content)

            /* 换行 */
            flex-wrap: wrap;
            /* 起点对齐 */
            /* align-content: flex-start; */

            /* 终点对齐 */
            /* align-content: flex-end; */

            /* 居中对齐 */
            /* align-content: center; */

            /* 环绕对齐 */
            /* align-content: space-around; */

            /* 两端对齐 */
            /* align-content: space-between; */

            /* 默认 */
            /* align-content: stretch; */

注意:必须在换行的前提下设置
UTOOLS1586529318483.png
UTOOLS1586529388158.png

5.六面骰子案例

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .container {
            position: relative;
            width: 200px;
            height: 200px;
            margin: 100px auto;
            transform-style: preserve-3d;
            animation: tou 1s infinite linear;
        }

        @keyframes tou {
            0% {
                transform: rotate(0);
            }

            100% {
                transform: rotateX(360deg) rotateY(360deg);
            }
        }

        .container:hover {
            animation-play-state: paused;
        }

        section[class ^='box'] {
            position: absolute;
            top: 0;
            left: 0;
            display: flex;
            width: 200px;
            height: 200px;
            margin-top: 10px;
            background-color: #09f;
            padding: 20px;
            border: 1px solid #000;
        }

        section .dot {
            width: 30px;
            height: 30px;
            background-color: #000;
            border-radius: 50%;
        }

        /* 前面 */
        .box1 {
            transform: translateZ(120px);
            justify-content: center;
            align-items: center;
        }

        /* 后面 */
        .box2 {
            transform: translateZ(-120px);
            flex-direction: column;
            justify-content: space-between;
            align-items: center;
        }

        /* 左面 */
        .box3 {
            transform: rotateY(90deg) translateZ(120px);
            justify-content: space-between;
        }

        .box3 div:nth-child(2) {
            align-self: center;
        }

        .box3 div:nth-child(3) {
            align-self: flex-end;
        }

        /* 右面 */
        .box4 {
            transform: rotateY(-90deg) translateZ(120px);
            flex-direction: column;
            justify-content: space-between;
        }

        .info {
            display: flex;
            justify-content: space-between;
        }

        /* 上面 */
        .box5 {
            transform: rotateX(90deg) translateZ(120px);
            flex-direction: column;
            justify-content: space-between;
        }

        .box5>.dot {
            align-self: center;
        }

        .box6 {
            transform: rotateX(-90deg) translateZ(120px);
            flex-direction: column;
            justify-content: space-between;
        }
    </style>
</head>

<body>
    <div class="container">
        <section class="box1">
            <div class="dot"></div>
        </section>
        <section class="box2">
            <div class="dot"></div>
            <div class="dot"></div>
        </section>
        <section class="box3">
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
        </section>
        <section class="box4">
            <div class="info">
                <div class="dot"></div>
                <div class="dot"></div>
            </div>
            <div class="info">
                <div class="dot"></div>
                <div class="dot"></div>
            </div>
        </section>
        <section class="box5">
            <div class="info">
                <div class="dot"></div>
                <div class="dot"></div>
            </div>
            <div class="dot"></div>
            <div class="info">
                <div class="dot"></div>
                <div class="dot"></div>
            </div>
        </section>
        <section class="box6">
            <div class="info">
                <div class="dot"></div>
                <div class="dot"></div>
            </div>
            <div class="info">
                <div class="dot"></div>
                <div class="dot"></div>
            </div>
            <div class="info">
                <div class="dot"></div>
                <div class="dot"></div>
            </div>
        </section>
    </div>
</body>

</html>

6.第四面详讲

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .container {
            /* 2.将大盒子设为容器 */
            display: flex;
            /* 3.转换主轴方向 */
            flex-direction: column;
            /* 4.主轴两端对齐 */
            justify-content: space-between;
            width: 150px;
            height: 150px;
            margin: 100px auto;
            background-color: #09f;
            padding: 30px;
        }

        section .info {
            /* 1.设为容器,子项沿主轴两端对齐 */
            display: flex;
            justify-content: space-between;
            border: 1px solid #000;
        }

        section .info .dot {
            width: 30px;
            height: 30px;
            background-color: #000;
            border-radius: 50%;
        }
    </style>
</head>

<body>
    <section class="container">
        <div class="info">
            <div class="dot"></div>
            <div class="dot"></div>
        </div>
        <div class="info">
            <div class="dot"></div>
            <div class="dot"></div>
        </div>
    </section>
    </div>
</body>

</html>

UTOOLS1586575813497.png
UTOOLS1586575860244.png
UTOOLS1586575881585.png

7.flex-flow属性

flex-flow 属性是 flex-direction 和 flex-wrap 属性的复合属性

            flex-flow:row wrap;
            /* 复合写法,没有顺序 */
            flex-flow: column wrap;

三.flex中的子项属性

1.order属性

order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。

        .info1 {
            order: 1;
        }

        .info3 {
            order: -1;
        }

UTOOLS1586576146683.png

3.align-self属性

        .info2 {
            align-self: center;
        }

        .info3 {
            align-self: flex-end;
        }

UTOOLS1586576392502.png

4.flex属性

4.1 flex-grow

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            display: flex;
            width: 400px;
            height: 350px;
            margin: 50px auto;
            background-color: #f34;
            border: 2px solid #000;
        }

        /* 子相可以设置宽高 */
        span {
            width: 50px;
            height: 50px;
            margin: -1px;
            background-color: #09f;
            border: 2px solid #fff;
        }

        /* order是定义子项的排列顺序,默认值是0,数字越小,排列越靠前 */
        .box1 span:nth-child(3) {
            order: -1;
        }

        .box1 span:first-child {
            order: 1;
        }

        .box2 {
            align-items: center;
        }

        /* align-self是单独控制自己在侧轴上的排列方式 */
        .box2 span:first-child {
            align-self: flex-start;
        }

        .box2 span:nth-child(3) {
            align-self: flex-end;
        }

        /* flex-grow:是子项占父项目宽度 */
        .box3 span:first-child {
            flex-grow: 2;
        }

        .box3 span:nth-child(3) {
            flex-grow: 1;
        }

        /* flex-shrink:表示当flex容器空间不足是,会将子项进行收缩,默认是1,0表示不收缩,值越大收缩越厉害 */
        .box4 span:first-child {
            flex-shrink: 0;
        }

        .box4 span:nth-child(3) {
            flex-shrink: 2;
        }

        /* flex-basis:定义分配空间前子项的默认大小 */
        .box5 span:first-child {
            flex-basis: 10px;
        }

        .box5 span:nth-child(3) {
            flex-basis: 100px;
        }

        /* flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。 */
        .box6 span:first-child {
            flex: 0 0 30px;
        }

        .box6 span:nth-child(3) {
            flex: 1 1 auto;
        }
    </style>
</head>

<body>
    <div class="box1">
        <span>1</span>
        <span>2</span>
        <span>3</span>
        <span>4</span>
        <span>5</span>
    </div>
    <div class="box2">
        <span>1</span>
        <span>2</span>
        <span>3</span>
        <span>4</span>
        <span>5</span>
    </div>
    <div class="box3">
        <span>1</span>
        <span>2</span>
        <span>3</span>
        <span>4</span>
        <span>5</span>


    </div>
    <div class="box4">
        <span>1</span>
        <span>2</span>
        <span>3</span>
        <span>4</span>
        <span>5</span>
        <span>1</span>
        <span>2</span>
        <span>3</span>
        <span>4</span>
        <span>5</span>
    </div>
    <div class="box5">
        <span>1</span>
        <span>2</span>
        <span>3</span>
        <span>4</span>
        <span>5</span>
    </div>
    <div class="box6">
        <span>1</span>
        <span>2</span>
        <span>3</span>
        <span>4</span>
        <span>5</span>
    </div>
</body>

</html>

UTOOLS1586963811231.png

4.1 flex-shrink

    <div class="container container2">
        <div class="info">1</div>
        <div class="info">2</div>
        <div class="info">3</div>
        <div class="info">4</div>
        <div class="info">5</div>
        <div class="info">1</div>
        <div class="info">2</div>
        <div class="info">3</div>
        <div class="info">4</div>
        <div class="info">5</div>
    </div>
        /* flex-shrink:表示当flex容器空间不足是,会将子项进行收缩,默认是1,0表示不收缩,值越大收缩越厉害 */
        .container2 .info:first-child {
            flex-shrink: 0;
        }

        .container2 .info:nth-child(3) {
            flex-shrink: 2;
        }

        .container2 .info:nth-child(6) {
            flex-shrink: 5;
        }

UTOOLS1586964121126.png

4.1 flex-basis

    <div class="container container3">
        <div class="info">1</div>
        <div class="info">2</div>
        <div class="info">3</div>
        <div class="info">4</div>
        <div class="info">5</div>
    </div>
        /* flex-basis:定义分配空间前子项的默认大小 */
        .container3 .info:first-child {
            flex-basis: 10px;
        }

        .container3 .info:nth-child(3) {
            flex-basis: 100px;
        }

        .container3 .info:nth-child(5) {
            flex-basis: 20%;
        }

UTOOLS1586964303463.png

4.4 flex

        /* flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。 */
        .container4 .info:first-child {
            flex: 0 0 30px;
        }

        .container4 .info:nth-child(3) {
            flex: 1 1 auto;
        }

        .container4 .info:nth-child(5) {
            flex: 1;
        }
    <div class="container container4">
        <div class="info">1</div>
        <div class="info">2</div>
        <div class="info">3</div>
        <div class="info">4</div>
        <div class="info">5</div>
    </div>

一般情况下flex只写一个值,表示子项占父项的份数,例如有6个盒子,每个flex=1;那么每个盒子都占父相的1/6.

相关推荐:
在线演示flex网站
https://demos.scotch.io/visual-guide-to-css3-flexbox-flexbox-playground/demos/

posted @ 2020-04-19 08:44  小艾同学喔  阅读(138)  评论(0编辑  收藏  举报