前端开发那些事儿

CSS3 Flexible Box Layout

2020-08-27  本文已影响0人  深度剖析JavaScript

在传统的布局中,我们常常使用定位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布局的全部属性和用法!

上一篇下一篇

猜你喜欢

热点阅读