[图解]-你知道的flex布局

325 阅读5分钟

flex

flex布局.png

基本概念

要了解flex布局,首先需要了解两个核心的概念 容器

基本概念.png

容器

  • 父容器(container): 添加了属性display:flex的容器
  • 子容器(item):父容器的直接子元素

  • 主轴(main axis):默认从左到右。
  • 交叉轴(cross axis):垂直于主轴,默认从上到下。

父容器

flex-direction

指定主轴方向,副轴垂直于主轴,默认值为row。

<style>
    .container {
        display: flex;
        width: 400px;
        height: 250px;
         flex-direction:? 
        border: 1px solid rgba(0, 0, 0, 1);
    }

    .item1 {
        width: 100px;
        height: 100px;
        background-color: rgb(135, 206, 250);
    }

    .item2 {
        width: 100px;
        height: 100px;
        background-color: rgb(127, 255, 170);
    }
</style>
<body>
    <div class="container">
        <div class="item1"></div>
        <div class="item2"></div>
    </div>
</body>
  • flex-direction:row 指定主轴为横轴,方向从左到右. 👇 无标题.png
  • flex-direction:row-reverse 指定主轴为横轴,方向从右到左👇 fdrr.png
  • flex-direction:column 指定主轴为竖轴方向从上到下👇 fdc.png
  • flex-direction:column-reverse 指定主轴为竖轴方向从下到上👇

fdcr.png

flex-wrap

设置子容器是否换行,换行后是否逆序,默认值为nowrap。

<style>
    .container {
        display: flex;
        width: 250px;
        height: 250px;
        flex-wrap:?; //
        border: 1px solid rgba(0, 0, 0, 1);
    }
    .item1 {
        width: 100px;
        height: 100px;
        background-color: rgb(135, 206, 250);
    }
    .item2 {
        width: 100px;
        height: 100px;
        background-color: rgb(127, 255, 170);
    }
    .item3{
        width: 100px;
        height: 100px;
        background-color: rgb(190, 172, 172);
    }
</style>
<body>
    <div class="container">
        <div class="item1"></div>
        <div class="item2"></div>
        <div class="item3"></div>
    </div>
</body>
  • flex-wrap:nowrap 不换行👇

frn.png

  • flex-wrap:wrap 超出父容器宽度则换行👇

frw.png

  • flex-wrap:wrap-reverse 超出父容器宽度则逆序换行👇

frwr.png

flex-flow

flex-flow是 flex-direction 和 flex-wrap 的简写

justify-content

控制子容器未填满父容器主轴时,子容器在主轴上所在的位置以及间距。

<style>
    .container {
        display: flex;
        width: 350px;
        height: 250px;
        justify-content:?; //
        border: 1px solid rgba(0, 0, 0, 1);
    }
    .item1 {
        width: 100px;
        height: 100px;
        background-color: rgb(135, 206, 250);
    }
    .item2 {
        width: 100px;
        height: 100px;
        background-color: rgb(127, 255, 170);
    }
    .item3{
        width: 100px;
        height: 100px;
        background-color: rgb(190, 172, 172);
    }
</style>
<body>
    <div class="container">
        <div class="item1"></div>
        <div class="item2"></div>
        <div class="item3"></div>
    </div>
</body>
  • flex-start 子容器对齐主轴的起点👇

jcfs.png

  • center 子容器在主轴上居中👇

jcc.png

  • flex-end 子容器对齐主轴的终点👇

jcfe.png

  • space-between 子容器两端对齐,间距相等。👇

jcsb.png

  • space-around 最两边的间距是中间间距的一半。👇 jcba.png

align-items

控制子容器未填满父容器交叉轴时,子容器在交叉轴上所在的位置。

<style>
    .container {
        display: flex;
        width: 350px;
        height: 250px;
        align-items: ?; //
        border: 1px solid rgba(0, 0, 0, 1);
    }
    .item1 {
        width: 100px;
        height: 100px;
        background-color: rgb(135, 206, 250);
    }
    .item2 {
        font-size: 25px;
        width: 100px;
        height: 100px;
        background-color: rgb(127, 255, 170);
    }
    .item3{
        font-size: 35px;
        width: 100px;
        height: 100px;
        background-color: rgb(190, 172, 172);
    }
</style>
<body>
    <div class="container">
        <div class="item1"></div>
        <div class="item2"></div>
        <div class="item3"></div>
    </div>
</body>
  • flex-start 子容器对齐交叉轴的起点👇 jcfs.png
  • center 子容器在交叉轴上居中👇

aic.png

  • flex-end 子容器对齐交叉轴的终点👇

aife.png

  • stretch 默认属性,子容器在交叉轴上不设置距离(此处为高)或auto时,长度铺满父容器。👇 此处将item1的高度去除或设为auto. ais.png 此处以竖轴为主轴,并将item1的宽度去除或设为auto(此处主轴子容器超过父容器产生了收缩,下面会讲到收缩.)👇

ais2.png

  • baseline 以文字的基准对齐👇

aib.png

align-content

控制多行子容器在交叉轴上的位置,以及间距。(如果子容器没有换行,align-content就会被忽略)

<style>
    .container {
        display: flex;
        width: 250px;
        height: 250px;
        flex-wrap: wrap;
        align-content: ?; //
         border: 1px solid rgba(0, 0, 0, 1);
    }
    .item1 {
        width: 100px;
        width: 100px;
        background-color: rgb(135, 206, 250);
    }
    .item2 {
        width: 100px;
        height: 100px;
        background-color: rgb(127, 255, 170);
    }
    .item3 {
        width: 100px;
        height: 100px;
        background-color: rgb(190, 172, 172);
    }
</style>
<body>
    <div class="container">
        <div class="item1"></div>
        <div class="item2"></div>
        <div class="item3"></div>
    </div>
</body>
  • flex-start 子容器对齐交叉轴起点👇

acfs.png

  • center 子容器在交叉轴上居中👇

acc.png

  • flex-end 子容器对齐交叉轴终点👇

acfe.png

  • stretch 默认属性,在交叉轴上未设置距离或为auto,子容器将会拉伸。👇 此处将item1的高度去除,或为auto. item1被拉伸。

acs.png

  • space-between 子容器在交叉轴两端对齐,间距相等👇

acsb.png

  • space-around 子容器在交叉轴上最两边的间距是中间间距的一半。👇

acsa.png

子容器

flex-basis

flex-basis定义了子容器的基准值 单位可为px,em,百分比,默认为auto.(此处的宽度为主轴上所占的距离,当主轴变为竖轴,则为高)

flex-basis.png

image.png

flex-grow

flex-grow定义了子容器的伸展程度。 当子容器未铺满父容器的长度,剩余部分会按flex-grow比例分别分配给子容器。(此处的长度为主轴上所占的距离,当主轴变为竖轴,则为高),默认值为0.

image.png

flex-shrink

flex-shrink定义了子容器的收缩程度,当子容器超过父容器的宽度,他的计算分摊公式和flex-grow不一样,默认值为1。
某子容器需要压缩的值:(某子容器的flex-shrink值 * 某子容器的flex-basis值) / (各子容器flex-shrink值 * flex-basis值的总和) * 超出部分的宽度

image.png

flex

flex属性为:flex-grow flex-shrink flex-basis的简写。
当忽略某一个值是,在此处(设置了flex属性)flex-grow默认为1,flex-shrink默认为1,flex-basis默认为0%。

  • flex:1   ---> 1 1 0% --->flex-grow:1,flex-shrink:1,*flex-basis:0%*👇

image.png

  • flex:2   ---> 2 1 0% --->flex-grow:2,flex-shrink:1,*flex-basis:0%*👇

image.png

  • flex:50px   ---> 1 1 50px --->flex-grow:1,flex-shrink:1,flex-basis:50px👇

image.png

  • flex:2 50px   ---> 2 1 50px --->flex-grow:2,flex-shrink:1,flex-basis:50px👇

image.png

  • flex:50px 2   ---> 2 1 50px --->flex-grow:2,flex-shrink:1,flex-basis:50px👇

image.png

  • flex:1 2   ---> 1 2 0% --->flex-grow:1,flex-shrink:2,*flex-basis:0%*👇

image.png

  • flex:1 2 200px   ---> 1 2 150px --->flex-grow:1,flex-shrink:2,flex-basis:200px;👇

image.png

  • flex:200px 1 2   ---> 1 2 150px --->flex-grow:1,flex-shrink:2,flex-basis:200px;👇

image.png 结论:flex:2 50px和flex:50px 2效果一样,所以当有单位的值出现时会自动匹配flex-basis,当无单位的值出现时优先匹配flex-grow。

order

改变子容器在父容器中的排列顺序 (默认值为0,可为负值,值越大越靠近主轴的终点,值相同则按源码顺序)

    <div class="container">
        <div class="item1"></div>
        <div class="item2"></div>
    </div>

o.png 以竖轴为主轴(flex-direction:column)👇

oc.png

align-self

控制子容器在交叉轴上的对齐方式,默认为align-self:auto。

align-self.png

as.png

应用

flex实现圣杯布局

圣杯布局:两边宽度固定,中间宽度自适应,中间先渲染(圣杯布局和双飞翼布局效果相同,实现方式不同)。

image.png

<style>
body{
    width: 500px;
}
.header{
    width: 100%;
    height: 40px;
    background-color: rgb(205, 226, 231);
}
.container{
    width: 500px;
    height: 200px;
    display: flex;
}
.middle{
    flex: 1;
    background-color: rgb(187, 187, 226);
    order: 1;
}
.left{
    flex:0 0 100px;
    background-color: rgb(118, 187, 118);
}
.right{
    flex:0 0 100px;
    background-color: rgb(221, 184, 184);
    order: 2;
}
.footer{
    width: 100%;
    height: 40px;
    background-color: rgb(145, 125, 140);
}
</style>
<body>
    <div class="header">header</div>
    <div class="container">
        <div class="middle">middle</div>
        <div class="left">left</div>
        <div class="right">right</div>
    </div>
    <div class="footer">footer</div>
</body>

实现两栏等高

image.png

<style>
    body {
        width: 500px;
    }

    .header {
        width: 100%;
        height: 40px;
        background-color: rgb(205, 226, 231);
    }

    .container {
        width: 500px;
        display: flex;
    }
    .main {
        flex: 2;
        background-color: rgb(118, 187, 118);
    }

    .siderBar {
        flex: 1;
        background-color: rgb(221, 184, 184);
    }
    .moudle1{
        background-color:rgb(233, 123, 123);
    }
    .moudle2{
        background-color: rgb(162, 162, 218);
    }

    .footer {
        width: 100%;
        height: 40px;
        background-color: rgb(145, 125, 140);
    }
</style>
<body>
    <div class="header">header</div>
    <div class="container">
        <div class="main">
            <h1>main</h1><h1>main</h1>
        </div>
        <div class="siderBar">
            <div class="moudle1">moudle1</div>
            <div class="moudle2">moudle2</div>
        </div>
    </div>
    <div class="footer">footer</div>
</body>
将siderBar也设为父容器,以竖轴为主轴,多出的部分均分给module1和module2.
.siderBar {
        flex: 1;
        background-color: rgb(221, 184, 184);
        display: flex;
        flex-direction: column;
    }
.moudle1{
        background-color:rgb(233, 123, 123);
        flex-grow:1;
    }
.moudle2{
        background-color: rgb(162, 162, 218);
        flex-grow:1;
    }

image.png 刚开始用flex布局居中时容易把justify-content的align-items决定对齐的轴记反了,我是这样记的,韭菜(jc)站一排(主轴默认为横轴情况下)。

f50px.png 本篇文章如有错误欢迎各位大佬斧正,谢谢。