CSS3 Flexible Box Layout

作者: 深度剖析JavaScript | 来源:发表于2020-08-27 17:31 被阅读0次

    在传统的布局中,我们常常使用定位position、margin、浮动float等来实现页面的布局,虽然功能可以实现没有问题,但是它有缺点不够灵活,用起来比较费劲。比如我要实现多个同级元素在父级容器中水平垂直居中,float做不到,可以通过position定位来实现,但那当设置position:absolute时,所被设置的元素都会因为脱离文档流而重叠在一起,每个元素的有确切的位置,那就得计算每个元素应该在的位置,这样不太好吧,一来,计算太麻烦,二来后面如果父级再增加或者删除一些子元素那又得重新计算,那想想就头大,而且这样的情况还不少。

    <head>
        <style type="text/css">
            .wraper{
                width: 400px;
                height: 250px;
                background-color: pink;
                margin: 150px auto; 
                overflow: hidden;
                position: relative;
            }
            .wraper *{
                box-sizing: border-box;
                background-color: deeppink;
                border:1px solid #0e0;
                width: 80px;
                height: 80px;
                text-align: center;
                line-height: 80px;
                float: left;
                position: absolute;         
            }
            /*设置位置*/
            .wraper div:nth-of-type(1){
                left: 80px;
                top: 85px;
            }
            .wraper div:nth-of-type(2){
                left: 160px;
                top: 85px;
            }       
            .wraper div:nth-of-type(3){
                left: 240px;
                top: 85px;
            }       
        </style>
    </head>
    <body>
        <div class="wraper">
            <div>1</div>
            <div>2</div>
            <div>3</div>
        </div>
    </body>
    
    定位实现多元素水平垂直居中

    当然也可以给要居中的元素添加一个额外的父级,通过margin来实现

    <head>
        <style type="text/css">
            .wraper {
                width: 400px;
                height: 250px;
                background-color: pink;
                margin: 150px auto;
                overflow: hidden;
            }
    
            .wraper section * {
                box-sizing: border-box;
                background-color: deeppink;
                border: 1px solid #0e0;
                width: 80px;
                height: 80px;
                text-align: center;
                line-height: 80px;
                float: left;
            }
            .wraper section{
                margin:0 auto;
                width: 240px;
                height: 80px;
                margin-top:75px;
            }
            .clearFloat::after{
                clear: both;
                content: "";
                display: block;
            }
        </style>
    </head>
    <body>
        <div class="wraper">
            <section class="clearFloat">
                <div>1</div>
                <div>2</div>
                <div>3</div>
            </section>
        </div>
    </body>
    

    效果跟上面一模一样,这里是通过给父级设置margin:0 auto设置水平居中,通过调整margin-top让其水平居中。但是这样也麻烦,一 得清除浮动带来的影响,二 添加的父级得计算一下宽高,三 也是最不好的 为了样式修改了HTML结构。
    正是有这样那样的问题,在CSS2升级到CSS3时新增了Flex布局方式,这种方式也叫弹性布局、伸缩布局。一起来看看

    由于属性比较多我将其分父级容器和子级项两类记忆,整理如下图:

    在讲之前我想先铺垫一个知识点,那就是主轴和侧轴
    CSS3中引入了轴向的概念,包括主轴和侧轴。这跟我们平时说的水平X轴和垂直Y轴有点区别,在这轴向是可以改变的,主轴和侧轴不一定对应就是水平或者垂直方向。
    在flex布局中,容器的轴向是主还是侧是由flex容器中的属性设定,轴的两端起点和终点分别对应flex-start和flex-end,子级项目对齐和排列方式均以设定的轴向为基准。在默认情况下主轴就是水平方向,起点在左,终点在右;侧轴就是垂直方向,起点在上,终点在下
    通过display: flex即可激活元素的Flex特性,注意仅对容器内的第一层元素起作用,在容器外或者容器内的孙子辈的不起作用。

    下面开始讲解Flex布局中用到的属性及属性值
    首先是父级容器上的属性
    1. flex-direction
    flex-direction 用于设置主轴方向,对应的值有row、 row-reverse、 column、 column-reverse,分别表示水平、水平翻转、垂直、垂直翻转

    <head>
        <style type="text/css">
            body>div{
                float: left;
            }
            .wrapper {
                width: 280px;
                height: 280px;
                background-color: rgb(247, 176, 188);
                margin: 10px;
                overflow: hidden;
                display: flex;
            }
            .wrapper div{
                box-sizing: border-box;
                background-color: rgb(255, 40, 154);
                width: 60px;
                height: 60px;
                text-align: center;
                line-height: 60px;
            }
            .wrapper div:nth-of-type(2n){
                background-color: rgb(167, 82, 127);
            }
            .wrapper.one{
                flex-direction: row;
            }
            .wrapper.two{
                flex-direction: row-reverse;
            }
            .wrapper.three{
                flex-direction: column;
            }
            .wrapper.four{
                flex-direction: column-reverse;
            }
        </style>
    </head>
    
    <body>
        <div class="wrapper one">
            <div>1</div>
            <div>2</div>
            <div>3</div>
            <div>4</div>
        </div>
        <div class="wrapper two">
            <div>1</div>
            <div>2</div>
            <div>3</div>
            <div>4</div>
        </div>
        <div class="wrapper three">
            <div>1</div>
            <div>2</div>
            <div>3</div>
            <div>4</div>
        </div>
        <div class="wrapper four">
            <div>1</div>
            <div>2</div>
            <div>3</div>
            <div>4</div>
        </div>
    </body>
    
    结果如图

    2. flex-wrap
    flex-wrap用于控制子级项排列超出边界时是否换行展示;取值可以是nowrap、wrap、wrap-reverse,分别表示不换行、换行、换行并且反转行

    <head>
        <style type="text/css">
            body>div{
                float: left;
            }
            .wrapper {
                width: 280px;
                height: 180px;
                background-color: rgb(247, 176, 188);
                margin: 10px;
                overflow: hidden;
                display: flex;
            }
            .wrapper div{
                box-sizing: border-box;
                background-color: rgb(255, 40, 154);
                width: 60px;
                height: 60px;
                text-align: center;
                line-height: 60px;
            }
            .wrapper div:nth-of-type(2n){
                background-color: rgb(167, 82, 127);
            }
            .wrapper.one{
                flex-wrap: nowrap;
            }
            .wrapper.two{
                flex-wrap: wrap;
            }
            .wrapper.three{
                flex-wrap: wrap-reverse;
            }
    
        </style>
    </head>
    
    <body>
        <div class="wrapper one">
            <div>1</div>
            <div>2</div>
            <div>3</div>
            <div>4</div>
            <div>5</div>
            <div>6</div>
            <div>7</div>
        </div>
        <div class="wrapper two">
            <div>1</div>
            <div>2</div>
            <div>3</div>
            <div>4</div>
            <div>5</div>
            <div>6</div>
            <div>7</div>
        </div>
        <div class="wrapper three">
            <div>1</div>
            <div>2</div>
            <div>3</div>
            <div>4</div>
            <div>5</div>
            <div>6</div>
            <div>7</div>
        </div>
    </body>
    
    结果展示

    3. flex-flow
    flex-flow表示流动,即文档流,其实就是flex-direction和flex-wrap的复合写法

    <head>
        <style type="text/css">
            body>div{
                float: left;
            }
            .wrapper {
                width: 280px;
                height: 180px;
                background-color: rgb(247, 176, 188);
                margin: 10px;
                overflow: hidden;
                display: flex;
            }
            .wrapper div{
                box-sizing: border-box;
                background-color: rgb(255, 40, 154);
                width: 60px;
                height: 60px;
                text-align: center;
                line-height: 60px;
            }
            .wrapper div:nth-of-type(2n){
                background-color: rgb(167, 82, 127);
            }
            .wrapper.one{
                flex-flow: nowrap row;
            }
    
        </style>
    </head>
    
    <body>
        <div class="wrapper one">
            <div>1</div>
            <div>2</div>
            <div>3</div>
            <div>4</div>
            <div>5</div>
            <div>6</div>
            <div>7</div>
        </div>
    </body>
    
    默认就是不换行 主轴水平从左往右

    4. justify-content
    justify-content用于设置主轴方向的对齐方式,取值有5个,分别是:flex-start、flex-end、center、space-between、space-around,表示主轴起点、主轴终点、居中、空白在元素与元素之间、空白环绕着元素

    <head>
        <style type="text/css">
            body>div{
                float: left;
            }
            .wrapper {
                width: 280px;
                height: 150px;
                background-color: rgb(247, 176, 188);
                margin: 10px;
                overflow: hidden;
                display: flex;
            }
            .wrapper div{
                box-sizing: border-box;
                background-color: rgb(255, 40, 154);
                width: 60px;
                height: 60px;
                text-align: center;
                line-height: 60px;
            }
            .wrapper div:nth-of-type(2n){
                background-color: rgb(167, 82, 127);
            }
            .wrapper.one{
                justify-content: flex-start;
            }
            .wrapper.two{
                justify-content: flex-end;
            }
            .wrapper.three{
                justify-content: center;
            }
            .wrapper.four{
                justify-content: space-between;
            }
            .wrapper.five{
                justify-content: space-around;
            }
        </style>
    </head>
    
    <body>
        <div class="wrapper one">
            <div>1</div>
            <div>2</div>
            <div>3</div>
        </div>
        <div class="wrapper two">
            <div>1</div>
            <div>2</div>
            <div>3</div>
        </div>
        <div class="wrapper three">
            <div>1</div>
            <div>2</div>
            <div>3</div>
        </div>
        <div class="wrapper four">
            <div>1</div>
            <div>2</div>
            <div>3</div>
        </div>
        <div class="wrapper five">
            <div>1</div>
            <div>2</div>
            <div>3</div>
        </div>
    </body>
    
    对应结果

    5. align-items
    align-items与justify-content对应,justify-content表示主轴方向的对齐方式,而align-items表示侧轴上的对齐方式。但是取值有点不同,align-items的取值有:flex-start、flex-end、center、baseline、stretch(默认值),分别表示起点对齐、终点对齐、居中对齐、基线对齐、拉伸对齐

    <head>
        <style type="text/css">
            body>div{
                float: left;
            }
            .wrapper {
                width: 280px;
                height: 200px;
                background-color: rgb(247, 176, 188);
                margin: 10px;
                overflow: hidden;
                display: flex;
                flex-flow: wrap;
            }
            .wrapper div{
                box-sizing: border-box;
                background-color: rgb(255, 40, 154);
                text-align: center;
                line-height: 60px;
            }
            .wrapper div:nth-of-type(2n){
                background-color: rgb(167, 82, 127);
            }
            .wrapper.one{
                align-items: flex-start;
            }
            .wrapper.two{
                align-items: flex-end;
            }
            .wrapper.three{
                align-items: center;
            }
            .wrapper.four{
                align-items: baseline;
            }
            .wrapper.five{
                align-items: stretch;
            }
        </style>
    </head>
    
    <body>
        <div class="wrapper one">
            <div>1</div>
            <div>2</div>
            <div>3</div>
        </div>
        <div class="wrapper two">
            <div>1</div>
            <div>2</div>
            <div>3</div>
        </div>
        <div class="wrapper three">
            <div>1</div>
            <div>2</div>
            <div>3</div>
        </div>
        <div class="wrapper four">
            <div>1</div>
            <div>基线</div>
            <div>3</div>
        </div>
        <div class="wrapper five">
            <div>1</div>
            <div>2</div>
            <div>3</div>
        </div>
    </body>
    
    结果
    6. align-content
    align-content 子类多行排列时,子类在侧轴方向的对齐方式。注意如果是一行,该属性无效。即需要设置换行或者换行翻转才行,取值跟justify-content一致
    <head>
        <style type="text/css">
            body>div{
                float: left;
            }
            .wrapper {
                width: 280px;
                height: 200px;
                background-color: rgb(247, 176, 188);
                margin: 10px;
                overflow: hidden;
                display: flex;
                flex-flow: wrap;
            }
            .wrapper div{
                box-sizing: border-box;
                background-color: rgb(255, 40, 154);
                width: 80px;
                text-align: center;
                line-height: 60px;
            }
            .wrapper div:nth-of-type(2n){
                background-color: rgb(167, 82, 127);
            }
            .wrapper.one{
                align-content: flex-start;
            }
            .wrapper.two{
                align-content: flex-end;
            }
            .wrapper.three{
                align-content: center;
            }
            .wrapper.four{
                align-content: space-between;
            }
            .wrapper.five{
                align-content: space-around;
            }
        </style>
    </head>
    
    <body>
        <div class="wrapper one">
            <div>1</div>
            <div>2</div>
            <div>3</div>
            <div>4</div>
            <div>5</div>
        </div>
        <div class="wrapper two">
            <div>1</div>
            <div>2</div>
            <div>3</div>
            <div>4</div>
            <div>5</div>
        </div>
        <div class="wrapper three">
            <div>1</div>
            <div>2</div>
            <div>3</div>
            <div>4</div>
            <div>5</div>
        </div>
        <div class="wrapper four">
            <div>1</div>
            <div>2</div>
            <div>3</div>
            <div>4</div>
            <div>5</div>
        </div>
        <div class="wrapper five">
            <div>1</div>
            <div>2</div>
            <div>3</div>
            <div>4</div>
            <div>5</div>
        </div>
    </body>
    
    结果分别对应,flex-start、flex-end、center、space-between、space-around

    接着来看子级项目的相关属性,其主要功能是控制子级项的自适应伸缩及分配
    1. align-self
    align-self用于设置子级项目自身在侧轴上的对齐方式,其实就是单独设置一些特殊子类的侧轴对齐方式,用于覆盖父级得align-items。所以优先级高于align-items。取值也与align-items一致:flex-start、flex-end、center、baseline、stretch

    <head>
        <style type="text/css">
            body>div{
                float: left;
            }
            .wrapper {
                width: 280px;
                height: 200px;
                background-color: rgb(247, 176, 188);
                margin: 10px;
                overflow: hidden;
                display: flex;
                align-items: flex-start;
            }
            .wrapper div{
                box-sizing: border-box;
                background-color: rgb(255, 40, 154);
                width: 50px;
                text-align: center;         
                line-height: 60px;
            }
            .wrapper div:nth-of-type(2n){
                background-color: rgb(167, 82, 127);
            }
            .wrapper.one div:nth-of-type(1){
                align-self: flex-start;         
            }
            .wrapper.one div:nth-of-type(2){
                align-self: flex-end;
            }
            .wrapper.one div:nth-of-type(3){
                align-self: center;
            }
            .wrapper.one div:nth-of-type(4){
                align-self: baseline;
            }
            .wrapper.one div:nth-of-type(5){
                align-self: stretch;
            }
        </style>
    </head>
    <body>
        <div class="wrapper one">
            <div>1</div>
            <div>2</div>
            <div>3</div>
            <div>4</div>
            <div>5</div>
        </div>
    </body>
    
    结果对应flex-start、flex-end、center、baseline、stretch
    2. order:n
    用于调整特定子类中在所有子类中的排序,n是整数,数值越小,排列越靠前,默认值为 0,可以是负数
    上例中将最后一个放到前面去
    .wrapper.one div:nth-of-type(5){
        align-self: stretch;
        order:-1;
    }
    
    结果

    我们知道Flex的特性是自适应伸缩,即按比例分配容器的剩余空间,下面几个属性跟这个有关。
    3. flex-grow
    flex-grow表示子项的扩展比例,默认0 不扩展。注意:行中要存在可分配的剩余空间,子项多行时,以行为单位进行扩展,即我这行只能在我这行的剩余空间中按比例分

    <head>
        <style type="text/css">
            body > div{
                float: left;
            }
            .wrapper {
                width: 280px;
                height: 200px;
                background-color: rgb(247, 176, 188);
                margin: 10px;
                overflow: hidden;
                display: flex;
                flex-flow: wrap;
            }
            .wrapper div{
                box-sizing: border-box;
                background-color: rgb(255, 40, 154);
                width: 50px;
                text-align: center;         
                line-height: 60px;
            }
            .wrapper div:nth-of-type(2n){
                background-color: rgb(167, 82, 127);
            }
            .wrapper.one div:nth-of-type(3){
                flex-grow: 1;           
            }
            .wrapper.one div:nth-of-type(7){
                flex-grow: 1;
            }
        </style>
    </head>
    <body>
        <div class="wrapper one">
            <div>1</div>
            <div>2</div>
            <div>3</div>
            <div>4</div>
            <div>5</div>
            <div>6</div>
            <div>7</div>
            <div>8</div>
        </div>
    </body>
    
    将每行的剩余空间作为1份分给最中间的元素

    3. flex-shrink
    flex-shrink用于定义子项的收缩比例,默认值为1,表示等比缩小,容器空间不足需要收缩时才有效果

    <head>
        <style type="text/css">
            body > div{
                float: left;
            }
            .wrapper {
                width: 280px;
                height: 200px;
                background-color: rgb(247, 176, 188);
                margin: 10px;
                overflow: hidden;
                display: flex;
            }
            .wrapper div{
                box-sizing: border-box;
                background-color: rgb(255, 40, 154);
                width: 50px;
                text-align: center;         
                line-height: 60px;
            }
            .wrapper div:nth-of-type(2n){
                background-color: rgb(167, 82, 127);
            }
            .wrapper.one div:nth-of-type(3){
                flex-shrink: 3;     
            }
        </style>
    </head>
    <body>
        <div class="wrapper one">
            <div>1</div>
            <div>2</div>
            <div>3</div>
            <div>4</div>
            <div>5</div>
            <div>6</div>
            <div>7</div>
            <div>8</div>
        </div>
    </body>
    
    结果
    5. flex-basis
    定义子项在主轴上的基准尺寸(初始大小)
    默认值:auto,即项目原定大小;如果设定值,则优先于项目原定大小
    6 flex
    flex是flex-grow, flex-shrink 和 flex-basis的简写。多个值以空格隔开,按既定顺序排列(grow、shrink、basis)

    以上就是Flex布局的全部属性和用法!

    相关文章

      网友评论

        本文标题:CSS3 Flexible Box Layout

        本文链接:https://www.haomeiwen.com/subject/tqmzjktx.html