flex布局

1、简介

Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。布局的传统解决方案,基于盒模型,依赖 display 属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。而Flex 布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持。任何一个容器都可以指定为 Flex 布局。

2、关于flex弹性盒模型

采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目"。
​ 对于某个元素只要声明了display: flex;,那么这个元素就成为了弹性容器,具有flex弹性布局的特性。如下:

<div class="father">
        <div class="son1">弹性元素1</div>
        <div class="son2">弹性元素2</div>
        <div class="son3">弹性元素3</div>
</div>
.father{
                width: 600px;
                height: 400px;
                background-color: antiquewhite;
                display:flex;
                margin-left: 50px;
                margin-top: 50px;
            }

            .son1{
                width: 100px;
                height: 100px;
                background-color: red;
            }

            .son2{
                width: 100px;
                height: 100px;
                background-color: blue;
            }

            .son3{
                width: 100px;
                height: 100px;
                background-color: green;
            }

在这里插入图片描述
flex盒模型特点:

  1. 每个弹性容器都有两根轴:主轴和交叉轴,两轴之间成90度关系。注意:水平的不一定就是主轴。
  2. 每根轴都有起点和终点,这对于元素的对齐非常重要。
  3. 弹性容器中的所有子元素称为<弹性元素>,弹性元素永远沿主轴排列
  4. 弹性元素也可以通过display:flex设置为另一个弹性容器,形成嵌套关系。因此一个元素既可以是弹性容器也可以是弹性元素

3、盒模型属性

3.1 容器属性

(1)flex-direction(控制主控方向)

主轴的方向处理
flex布局是一种一维布局模型,一次只能处理一个维度(一行或者一列)上的元素布局。flex布局大部分的属性都是作用于主轴的,在交叉轴上很多时候只能被动地变化
可以在弹性容器上通过flex-direction修改主轴的方向。如果主轴方向修改了,那么交叉轴就会相应地旋转90度,弹性元素的排列方式也会发生改变,因为弹性元素永远沿主轴排列

flex-direction属性的取值(排列方向)
(1)row(默认)(水平方向)
(2)row-reverse(水平相反方向)
(3)column(垂直方向)
(4)column-reverse(垂直相反方向)

例如,默认情况下的flex布局
在这里插入图片描述

例如,假设将主轴设置为水平相反方向
在这里插入图片描述

补充:再子元素中也使用flex布局会怎么样??如下

    <div class="father">
        <div class="son1">1
            <div class="son1_1">1</div>
            <div class="son1_2">2</div>
            <div class="son1_3">3</div>
        </div>
        <div class="son2">2</div>
        <div class="son3">3</div>
    </div>
            .father{
                width: 600px;
                height: 400px;
                background-color: antiquewhite;
                display:flex;
                flex-direction: row;
                margin-left: 50px;
                margin-top: 50px;
            }

            .son1{
                width: 100px;
                height: 100px;
                background-color: red;
                display: flex;
            }

            .son2{
                width: 100px;
                height: 100px;
                background-color: blue;
            }

            .son3{
                width: 100px;
                height: 100px;
                background-color: green;
            }
            
            .son1 *{
                background-color: yellow;
                width: 20px;
                height: 20px;
                border: 2px solid black;
            }

在这里插入图片描述

如果改变子元素中flex布局的主轴方向,flex-direction: row-reverse;
在这里插入图片描述

(2)flex-wrap(换行)

沿主轴方向的排列处理
弹性元素永远沿主轴排列,那么如果主轴排不下,该如何处理?可以通过设置flex-wrap属性可使得主轴上的元素不换行、换行、反向换行。
flex-wrap属性的取值:
(1)nowrap(默认)(不换行)
(2)wrap(换行)
(3)wrap-reverse(换行并反转)

假设,容器的宽度是600px,容器中有7个100px的子元素,有下面几种情况
(1)当主轴方向不换行时

            .father{
                width: 600px;
                height: 400px;
                background-color: antiquewhite;
                display:flex;
                flex-direction: row;
                margin-left: 50px;
                margin-top: 50px;
            }

            .son1{
                width: 100px;
                height: 100px;
                background-color: red;
                display: flex;
            }

            .son2{
                width: 100px;
                height: 100px;
                background-color: blue;
            }

            .son3{
                width: 100px;
                height: 100px;
                background-color: green;
            }
    <div class="father">
        <div class="son1">1</div>
        <div class="son2">2</div>
        <div class="son3">3</div>
        <div class="son1">4</div>
        <div class="son2">5</div>
        <div class="son3">6</div>
        <div class="son1">7</div>
    </div>

结果:
在这里插入图片描述

可以发现,原本flex盒子下600px只能存放6个宽度为100px的子元素的,但现在一行却存放了7个元素,并且这七个元素的宽度都改变了。所以这里就有个规律,在不换行的情况下,如果一行中所有子元素的总宽大于flex盒子的宽,那么子元素的宽就会随之改变,子元素的宽度 = 所有子元素的总宽/子元素个数
在这里插入图片描述

(2)主轴方向换行的情况下
flex-wrap:wrap;
1、如果子元素都是等宽的
在这里插入图片描述
2、如果子元素不等宽
在这里插入图片描述

(3)wrap-reverse同样表示换行,需要注意的是第一排会紧贴容器底部

(3) flex-flow

flex-flow属性是flex-directionflex-wrap属性的简写集合,默认属性为row nowrap,即横向排列,且不换行。

(4)justify-content(主轴上的元素对齐)

取值:
主轴上的对齐方式:
(1)flex-start(默认,向左对齐)
在这里插入图片描述
(2)flex-end(向右对齐)
在这里插入图片描述
(3)center(居中)
在这里插入图片描述
(4)space-between(左右两端对齐,即左右两侧项目都紧贴容器,且项目之间间距相等)
在这里插入图片描述
(5)space-around(项目之间间距为左右两侧项目到容器间距的2倍)
在这里插入图片描述
(6)space-evenly(项目之间间距与项目与容器间距相等,相当于除去项目宽度,平均分配了剩余宽度作为项目左右margin)
在这里插入图片描述

(5)align-items

用于控制项目在交叉轴排列方式,默认stretch即如果项目没设置高度,或高度为auto,则占满整个容器。
取值:
(1)flex-start(让项目在交叉轴紧贴容器顶部)
在这里插入图片描述
(2)flex-end(与flex-start相反)
在这里插入图片描述
(3)center(在交叉轴中心位置排列)
在这里插入图片描述
(4)baseline(让项目以第一行文字的基线为参照进行排列)
在这里插入图片描述
(5)stretch(默认)
在这里插入图片描述

注意
(1)常理来说justify-content与align-items默认分别处理项目主轴,交叉轴的对齐方式,但如果我们修改了flex-direction为column,它们处理的轴向会交换,也就是justify-content处理交叉轴,align-items处理主轴。
(2)通过给一个父元素设置justify-content:center;align-items:center;可以使得其子元素垂直水平居中。

(6)align-content

作用:用于控制多行项目的对齐方式,如果项目只有一行则不会起作用,所以需设置flex-wrap: wrap;
取值:
(1)flex-start(让项目在交叉轴紧贴容器顶部)
在这里插入图片描述

(2)flex-end(让项目在交叉轴紧贴容器底部)
在这里插入图片描述
(3)center(让项目在交叉轴中心位置排列)
在这里插入图片描述
(4)space-between(上下两侧项目紧贴容器,上下项目之间间距相等)
在这里插入图片描述
(5)space-around(上下两侧项目之间间距为上下两侧项目与容器间距两倍。)
在这里插入图片描述
(6)space-evenly(上下两侧项目之间间距与上下两侧项目到容器之间间距相等)
在这里插入图片描述

(7)stretch(自动拉伸子元素)
在这里插入图片描述

3.2 项目属性

容器属性是加在父容器上的,而项目属性,就是写在项目/弹性元素上的,就好比容器属性给ul,项目属性给li差不多一个意思。

(1)order

取值:默认为0
作用:用于决定项目排列顺序,数值越小,项目排列越靠前

(2)flex-grow

取值:默认为0,用于决定项目在有剩余空间的情况下是否放大,默认不放大。补充:即便设置了固定高度同样也会放大。

第一种情况:假设默认三个项目中前两个个项目都是0,最后一个是1,最后的项目会占满剩余所有空间。
在这里插入图片描述
第二种情况:假设只有第一个项目默认为0,后面两个项目flex-grow均为1,那么后两个项目平分剩余空间
在这里插入图片描述
第三种情况:假设第一个项目默认为0,第二个项目为flex-grow:2,最后一个项目为1,则第二个项目在放大时所占空间是最后项目的两倍。
在这里插入图片描述

(3)flex-shrink

取值:默认为1
作用:用于决定项目在空间不足时是否缩小,即空间不足时整体一起等比缩小;注意,即便设置了固定宽度,也会缩小。但如果某个项目的flex-shrink设置为0,那么即便空间不够,自身也不会再缩小。

(4)flex-basis

取值:默认auto
作用:用于设置项目宽度,默认auto时,项目会保持默认宽度,或者以width为自身的宽度,但如果设置了flex-basis,权重会比width属性高,因此会覆盖width属性
在这里插入图片描述
上图中既设置了width又设置了flex-basis,但是却是以flex-basis为准。

(5)flex

作用:flex属性是flex-grow,flex-shrink与flex-basis三个属性的简写,用于定义项目放大,缩小与宽度。
取值:0 1 auto(默认)

div {
	flex:0.5;
}

表示

flex-grow 值为 1,即在空间分配时等比例扩展;
flex-shrink 值为 1,即在空间不足时等比例收缩;
flex-basis 值为 0.5,即基础大小为 flex 容器的宽度的一半。
div {
	flex:1;
}

表示

flex-grow 值为 1,即在空间分配时等比例扩展;
flex-shrink 值为 1,即在空间不足时等比例收缩;
flex-basis 值为 0%,项目的初始尺寸会变为 0,根据 flex-grow 和 flex-shrink 的值来调整
(6)align-self

作用:用于让个别项目拥有与其它项目不同的对齐方式,各值的表现与父容器的align-items属性完全一致
取值:(取值的作用同align-items一致)
(1)auto(默认)
(2)flex-start
(3)flex-end
(4)center
(5)baseline
(6)stretch

习题

习题一:模仿w3school网站的导航栏
请添加图片描述
代码实现:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>导航栏</title>
    <style>
        *{
            list-style: none;
            margin: 0;
            padding: 0;
        }

        div{
            margin:48px auto;
            padding: 0;
        }

        #menu{
            width: 1210px;
            height: 50px;
            background-color:#e8e7e3; 
            display: flex;
            justify-content: space-around;
            margin: auto;
            padding: 0;
        }


        li{
            /* display: block; */
            line-height: 48px;
            justify-content: space-around;
            flex-grow: 2;
            /* line-height: 50px; */
            text-align: center;
        }

        #menu a{
             text-decoration: none;
             color: #838382;
             display: block;
        }

        li:hover{
            background-color: rgb(174, 177, 177);
        }



    </style>
</head>
<body>
    <div>
        <ul id="menu">
            <li title="HTML/CSS 系列教程"><a href="#">HTML/CSS</a></li>
            <li title="浏览器脚本教程"><a href="#">Browser Side</a></li>
            <li title="服务器脚本教程"><a href="#">Server Side</a></li>
            <li title="编程教程"><a href="#">Programing</a></li>
            <li title="XML系列教程"><a href="#">XML</a></li>
            <li title="建站手册"><a href="#">WebBuilding</a></li>
            <li title="参考手册"><a href="#">Reference</a></li>
        </ul>
    </div>
</body>
</html>

习题二:模仿手机淘宝的导航栏
在这里插入图片描述
说明:图标可以随着网页放大而放大,缩小而缩小
代码实现如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=\, initial-scale=1.0">
    <title>淘宝导航栏</title>
    <style>
        *{
            margin: 0px;
            padding: 0px;
        }

        /*让父标签满足flex布局*/
        .outer{
            display: flex;
            /* 使得子标签div之间间距为左右两侧div标签到父标签间距的2倍*/
            justify-content: space-around;
            margin: 50px auto;
        }

        .inner{
            text-align: center;
            font-size: 20px;
        }

        div a{
            text-decoration: none;
            color: black;
        }
        
        /* 让图片填满整个div标签,使得其页面放大缩小时也能同比例放大缩小 */
        .inner img{
            width: 100%;
        }

    </style>
</head>
<body>
    <div class="outer">
        <div class="inner">
            <a href="#">
                <img src="../images/1.png" alt="天猫新品">
                <p>天猫精品</p>
            </a>
        </div>
        <div class="inner"> 
           <a href="#">
                <img src="../images/2.png" alt="今日暴饮">  
                <p>今日暴饮</p>
           </a>
        </div>

        <div class="inner">
            <a href="#">
                <img src="../images/3.png" alt="天猫国际">
                <p>天猫国际</p>
            </a>
        </div>
        <div class="inner">
           <a href="#">
                <img src="../images/4.png" alt="天猫市场">
                <p>天猫市场</p>
           </a>
        </div>
        <div class="inner">
            <a href="#">
                <img src="../images/5.png" alt="充值中心">
                <p>充值中心</p>
            </a>
        </div>
    </div>

    
    <div class="outer">
        <div class="inner">
            <a href="#">
                 <img src="../images/6.png" alt="机票酒店">
                 <p>机票酒店</p>
            </a>
         </div>
         <div class="inner">
            <a href="#">
                 <img src="../images/7.png" alt="金币庄园">
                 <p>金币庄园</p>
            </a>
         </div>
         <div class="inner">
             <a href="#">
                 <img src="../images/8.png" alt="阿里拍卖"> 
                 <p>阿里拍卖</p>
             </a>
         </div>
         <div class="inner">
             <a href="#">
                 <img src="../images/9.png" alt="淘宝吃货">
                 <p>淘宝吃货</p>
             </a>
         </div>
         <div class="inner">
             <a href="#">
                 <img src="../images/10.png" alt="分类">
                 <p>分类</p>
             </a>
         </div>
    </div>
</body>
</html>
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐