flexbox弹性盒布局学习笔记

194 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情

学习笔记

flexbox是一种一维的布局模型,相对的,grid为二维布局模型。

flexbox适合组件和小规模布局,grid适合大规模布局。

容器能够改变元素项的宽高和顺序,以最好地填充可适用空间(自适应各种显示设备和屏幕尺寸)

启用flexbox布局

.container {

    display: flex /*or inline-flex*/

}

启用flexbox布局的区域叫做flex容器。

设为 Flex 布局以后,子元素的floatclearvertical-align属性将失效。

flexbox属性总结

先贴一张cheatsheet。

下图中,左上角如果是紫色空心框,表示作用于flex 容器,如果是橙色实心框,表示作用于flex item项。

属性作用于flex容器(flex container,父元素),或flex元素项(felx items,子元素)

image.png

image.png

image.png

image.png

image.png

关于flex的缩写

单值语法:

  • flex: = flex-grow:,flex-shrink=1,flex-basis=0%
  • flex: width = flex-basis = width,width为有效的宽度值,带单位或者百分比,flex-grow=flex-shrink=1。
  • 关键字none,auto或initial

双值语法:

第一个值必须是无单位数,表示flex-grow,第二个数为:

  • number,表示flex-shrink,flex-basis=0%
  • 有效宽度值,表示flex-basis,flex-shrink=0

三值语法:

严格按顺序表示:flex-grow,flex-shrink,flex-basis

且前两个无单位非负数,后一个为有效的宽度值。

如果主轴是row,默认元素项会占据所有空间(列上会拉伸),排列成一行。

flex布局思想

两个轴:主轴msin axis,交叉轴cross axis

元素从主轴起始线开始排列,不会在主轴维度上拉伸,但可以缩小;

元素在主轴上溢出,会在交叉轴上填充,此时元素可被拉伸。

两条线:起始线和终止线

包括main start,main end和cross start, cross end

item沿主轴排列,占据主轴空间叫main size,交叉轴空间叫cross size

可用空间:flexbox容器有大小,其中内部元素占用一些空间,剩下的为可用空间。

利用属性flex-grow,flex-shrink,flex-basis来控制可用空间,最终决定flexbox内元素的对齐方式。

Main size/cross size:对应轴方向尺寸中的高度或宽度。

浏览器兼容

使用前缀,sass处理。引用下别人的,不是我写的。

@mixin flexbox() {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
}


@mixin flex($values) {
  -webkit-box-flex: $values;
  -moz-box-flex:  $values;
  -webkit-flex:  $values;
  -ms-flex:  $values;
  flex:  $values;
}

@mixin order($val) {
  -webkit-box-ordinal-group: $val;  
  -moz-box-ordinal-group: $val;     
  -ms-flex-order: $val;     
  -webkit-order: $val;  
  order: $val;
}


.wrapper {
  @include flexbox();
}

.item {
  @include flex(1 200px);
  @include order(2);
}

使用案例

  1. 居中布局
  2. 带页眉页脚的分列布局

源码如下。

index.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=device-width, initial-scale=1.0">
    <title>css定位</title>
    <link rel="stylesheet" href="flexbox.css">

<body>

    <h1>单元素居中定位</h1>
    <div class="parent">container
        <div class="child">item</div>
    </div>

    <h1>上部导航栏,右对齐</h1>
    <nav>
        <ul class="container-right">
            <li> <a href="#">home</a></li>
            <li> <a href="#">about</a></li>
            <li> <a href="#">products</a></li>
            <li> <a href="#">contact</a></li>
        </ul>
    </nav>


    <h1>上部导航栏,左对齐</h1>
    <nav>
        <ul class="container-left">
            <li> <a href="#">home</a></li>
            <li> <a href="#">about</a></li>
            <li> <a href="#">products</a></li>
            <li> <a href="#">contact</a></li>
        </ul>
    </nav>

    <h1>带有页眉页脚的3列布局</h1>

    <!-- 根据自适应,aside1,section,aside2会自适应。从行排列变成列排列-->

    <div class="wrapper">
        <header class="header">页眉</header>
        <aside class="aside1 aside">
            <ul>
                <li>list1</li>
                <li>list2</li>
            </ul>
        </aside>
        <article class="main">
            <p>
                Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.

            </p>
        </article>
        <aside class="aside2 aside">aside2</aside>
        <!-- <aside class="aside2 aside">aside3</aside> -->
        <footer class="footer">页脚</footer>
    </div>
</body>
</html>

flexbox.css

.parent {
    display: flex;
    height: 300px;
    border: 1px solid green;
}

.child {
    width: 100px;
    height: 100px;
    margin: auto;
    border: 1px solid red;
}

/*large*/
.container-right {
    display: flex;
    flex-flow: row wrap;
    justify-content: flex-end;
    list-style: none;
    background: deepskyblue;
}

.container-right a {
    text-decoration: none;
    display: block;
    padding: 1em;
    color: white;
}


.container-right a:hover {
    background: #1565c0;
}


/*medium screens*/
@media all and (max-width: 800px) {
    .container-right {
        justify-content: space-around;
    }
}

/*small size screens*/
@media all and (max-width: 600px) {
    .container-right {
        flex-direction: column wrap;
        padding: 0;

    }

    .container-right a {
        text-align: center;
        padding: 10px;
        border-top: 1px solid rbga(255, 255, 255, 0.3);
        border-bottom: 1px solid rbga(0, 0, 0, 0.1);

    }

    .container-right li:last-of-type a {
        border-bottom: none;
    }
}

/*------上部导航栏,左对齐-------*/

.container-left {
    display: flex;
    flex-flow: row wrap;
    list-style: none;
    justify-content: flex-start;
    /*内边距为0,左侧必须添加这个*/
    padding: 0;
    background: greenyellow;

}


.container-left a {
    text-decoration: none;
    display: block;
    padding: 1em;
    color: red;

}


.container-left a:hover {
    background: #1565c0;
}



/*medium screens*/
@media all and (max-width: 800px) {

    .container-left {

        justify-content: space-around;

    }

}



/*small size screens*/

@media all and (max-width: 600px) {

    .container-left {
        flex-direction: column wrap;
        padding: 0;

    }

    .container-left a {
        text-align: center;
        padding: 10px;
        border-top: 1px solid rbga(255, 255, 255, 0.3);
        border-bottom: 1px solid rbga(0, 0, 0, 0.1);

    }
    .container-left li:last-of-type a {
        border-bottom: none;
    }

}


/*-----带页眉页脚的3列分布----*/

.wrapper {

    display: flex;

    flex-flow: row wrap;

    font-weight: bold;

    text-align: center;

}



.wrapper > * {

    padding: 10px;

    /* 下面这句关键,导致分3行,默认1行,不缩小,基于元素主轴方向长度缩放 */

    /* 相当于:flex:1 1 100% 按照宽,扩大,子元素每项占一行*/

    flex: 1 100%;

    /* 默认:flex: 0 1 0px;  挤在一行,有缩放*/

}


.header {
    background: tomato;
}

.main {
    background: skyblue;
    text-align: left;
}

.aside1 {
    background: orange;
}

.aside2 {
    background: pink;
}


.footer {
    background: green;
}


@media all and (min-width: 600px) {
    .aside {
        /* 重要 */
        flex: 1 0 0;
    }
}


@media all and (min-width: 800px) {
    .main {
        /* flex: 3 1 0px,基于最小宽度,因为前面aside设置为按照0缩放,所以会和main挤在一行 */
        flex: 3 0px;
    }
    /* header默认order为0,在最上方,header占满一行 */
    .aside1 { 
        /* felx:1 0 0px */
        order: 1;
    }
    .main {
        order: 2;
    }

     /* felx:1 0 0px */

    .aside2 {

        order: 3;

    }

    /* 必须设置为最大值,放在最底下 */

     /* felx:1 1 100% */

    .footer {

        order: 4;

    }

}

效果图

参考资料

1.msdn:developer.mozilla.org/zh-CN/docs/…

2.css-tricks:css-tricks.com/snippets/cs…

3.讲解了flex属性的取值:www.zhangxinxu.com/wordpress/2…