美文网首页
flex:1及flex取值的理解

flex:1及flex取值的理解

作者: 锦锦_jane | 来源:发表于2020-05-10 01:23 被阅读0次

    1. flex布局

    参照:阮一峰的文章

    2. flex:1的理解

    2.1 概念

    • flex:flex-growflex-shrinkflex-basis的缩写,默认值为0 1 auto。后两个属性可选
    • 剩余空间:父容器在主轴方向上的可用空间。
      • 具有flex环境的父容器,通常是有一条主轴和一条侧轴,默认情况下,主轴就是水平从左向右,侧轴是垂直从上到下
      • 剩余空间 = 父元素宽度 - 所有子元素宽度的和


        剩余空间示例

    2.2 flex属性

    2.2.1 flex-grow

    • (1)概念:定义项目的放大比例,默认为0。即如果存在剩余空间,也不放大

      .item{
              flex-grow: <number>; /* default 0 */
      }
      
    • (2)取值:
      考虑情况:当父元素有剩余空间时,子元素如何分配父元素的剩余空间

      例:父元素width=400px,子元素A的width=100px,子元素B的width=200px。当A、B元素以不同比例索取剩余空间时,A、B元素的width分别是多少?

      <body>
        <div class="box">
            <div class="inner">A</div>
            <div class="inner1">B</div>
        </div>
      </body>
      

      剩余空间:400-(100+200)=100px

      • A、B都不索取剩余空间,有100px的剩余空间
      <style>
        .box {
            display: flex;
            flex-direction: row; /*设置主轴方向*/
            margin: 100px auto;
            width: 400px;
            height: 200px;
            border: 1px solid black;
        }
        .inner {
            flex-basis: 100px; /*相当于设置width*/
            height: 100px;
            background: teal;
        }
        .inner1 {
            flex-basis: 200px; /*相当于设置width*/
            height: 100px;
            background: skyblue;
        }
      </style>
      
      A、B都不索取剩余空间
      • A索取剩余空间:设置flex-grow:1,B不索取
      .inner {
          flex-basis: 100px; /*相当于设置width*/
          height: 100px;
          background: teal;
          flex-grow: 1; /*索取剩余空间*/
      }
      .inner1 {
          flex-basis: 200px; /*相当于设置width*/
          height: 100px;
          background: skyblue;
      }
      
      A索取剩余空间:设置`flex-grow:1`,B不索取

      计算A的宽度:自身宽度(100px)+剩余空间宽度(100px) = 200px

      • A、B都索取剩余空间,A设置flex-grow:1,B设置flex-grow:2
        .inner {
            flex-basis: 100px; /*相当于设置width*/
            height: 100px;
            background: teal;
            flex-grow: 1; /*索取剩余空间*/
        }
        .inner1 {
            flex-basis: 200px; /*相当于设置width*/
            height: 100px;
            background: skyblue;
            flex-grow: 2; /*索取剩余空间*/
        }
      
      A、B元素的width

      剩余空间分配公式
      分配到的剩余空间宽度 = 剩余空间宽度*(自身元素的flex-grow值/所有元素的flex-grow值的和)
      计算结果是:
      A分配到的剩余空间宽度 = 100px * (1/(1+2)) = 33.33px
      B分配到的剩余空间宽度 = 100px * (2/(1+2)) = 66.67px

    2.2.2 flex-shrink

    • (1)概念:定义项目的缩小比例,默认为1。即如果空间不足,该项目将缩小

      .item{
             flex-shrink: <number>; /* default 1 */
      }
      
      • 负值无效
      • 注:flex环境默认是不换行的,即使父容器宽度不够也不会,除非设置flex-wrap来换行
    • (2)取值:
      考虑情况:当子元素超出父元素时,子元素如何缩小自己的宽度

      例:父元素width=400px,子元素A的width=200px,子元素B的width=300px。当A、B元素设置不同的flex-shrink时,A、B元素的width分别是多少?

      <body>
        <div class="box">
            <div class="inner">A</div>
            <div class="inner1">B</div>
        </div>
      </body>
      

      超出宽度:(200+300)-400 = 100px

      • A、B都不减小宽度,都设置flex-shrink为0,则有100px超出父元素
      .box {
            display: flex;
            flex-direction: row; /*设置主轴方向*/
            margin: 100px auto;
            width: 400px;
            height: 200px;
            border: 1px solid black;
      }
      .inner {
            flex-basis: 100px; /*相当于设置width*/
            height: 100px;
            background: teal;
            flex-shrink: 0; /*不缩小宽度*/
      }
      .inner1 {
            flex-basis: 200px; /*相当于设置width*/
            height: 100px;
            background: skyblue;
            flex-shrink: 0; /*不缩小宽度*/
      }
      
      A、B不减小宽度的情况,有100px宽度超出
      • A不减小宽度,flex-shrink为0,B减小,flex-shrink为1
      .inner {
            flex-basis: 100px; /*相当于设置width*/
            height: 100px;
            background: teal;
            flex-shrink: 0; /*不缩小宽度*/
      }
      .inner1 {
            flex-basis: 200px; /*相当于设置width*/
            height: 100px;
            background: skyblue;
            flex-shrink: 1; /*缩小宽度*/
      }
      
      A不减小宽度,flex-shrink为0,B减小

      计算B的宽度:自身宽度(300px)-超出父元素的宽度(100px) = 200px

      • A、B都减小宽度,A设置flex-shrink为3,B设置flex-shrink为2
      .inner {
            flex-basis: 100px; /*相当于设置width*/
            height: 100px;
            background: teal;
            flex-shrink: 3; /*缩小宽度*/
      }
      .inner1 {
            flex-basis: 200px; /*相当于设置width*/
            height: 100px;
            background: skyblue;
            flex-shrink: 2; /*缩小宽度*/
      }
      
      A、B元素设置不同的flex-shrink的情况

      减小宽度计算公式:
      分配到的减小宽度 = 超出宽度*(自身宽度*(自身元素的flex-shrink值/所有子元素的flex-shrink值*自身宽度 的和))
      计算结果:
      A减小的宽度 = 100px * (200px * 3/(200 * 3 + 300 * 2))= 50px
      B减小的宽度 = 100px * (300px * 2/(200 * 3 + 300 * 2))= 50px

    2.2.3 flex-basis

    • (1)概念:定义了在分配多余空间之前,项目占据的主轴空间(main size)

       .item{
              flex-basis: <length> | auto; /* default auto */
       }
      
      • 浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小
    • (2)取值

      • 设置元素的宽度。当元素同时设置了widthflex-basis时,width的值会被flex-basis覆盖掉
      <style type="text/css" media="screen">
          .box{
              display: flex;
              margin: 100px auto;
              width: 400px;
              height: 200px;
          }
          .inner{
              width:200px;
              height:100px;
              flex-basis:300px;
              background:pink;
          }
      </style>
      </head>
      <body>
          <div class="box">
              <div class="inner"></div>
          </div>
      </body>
      
      当同时设置了width和flex-basis时,取flex-basis的值
      • flex-basis规定的是子元素的基准值。是否溢出计算与flex-basis属性相关。规定的范围取决于box-sizing。取值情况:
        • auto:首先检索该子元素的主尺寸,如果主尺寸不为 auto,则使用值采取主尺寸之值;如果也是 auto,则使用值为 content。
        • content:指根据该子元素的内容自动布局。有的用户代理没有实现取 content 值,等效的替代方案是 flex-basis 和主尺寸都取 auto。
        • 百分比:根据其包含块(即伸缩父容器)的主尺寸计算。如果包含块的主尺寸未定义(即父容器的主尺寸取决于子元素),则计算结果和设为 auto 一样。

    2.3 flex的取值

    • initial:即取上面三个属性的默认值,0 1 auto,在有剩余空间的情况下不会有任何变化,但是在必要的情况下会被收缩。

      • 子元素不设置宽度,宽度就为0
      • 在设置的子元素宽度总和 ≤ 父元素宽度时,即在有剩余空间的情况下,不会收缩
      • 在设置的子元素宽度总和 > 父元素宽度时,会收缩
    • none:计算值为0 0 auto,在任何情况都不会发生伸缩。等同于

      .item{ flex: 0 0 auto; }
      .item {
        flex-grow: 0;
        flex-shrink: 0;
        flex-basis: auto;
      }
      
    • auto:计算值为1 1 auto,会根据主轴自动伸缩以占用所有剩余空间。等同于

      .item{ flex: 1 1 auto; }
      .item {
          flex-grow: 1;
          flex-shrink: 1;
          flex-basis: auto;
      }
      
    • 一个非负数字:该数字为flex-grow 值,flex-shrink1flex-basis0%,等同于

      .item{ flex: 1; }
      .item {
          flex-grow: 1; /*非负数字表示的这个属性的值*/
          flex-shrink: 1;
          flex-basis: 0%;
      }
      
    • 一个长度或百分比:则视为 flex-basis 值,flex-grow1flex-shrink1,等同于(注意 0% 是一个百分比而不是一个非负数字):

      /*百分比形式的*/
      .item{ flex: 0%; }
      .item {
          flex-grow: 1; 
          flex-shrink: 1;
          flex-basis: 0%; /*百分比表示的这个属性的值*/
      }
      
      /*长度形式的*/
      .item{ flex: 24px; }
      .item {
          flex-grow: 1; 
          flex-shrink: 1;
          flex-basis: 24px; /*长度表示的这个属性的值*/
      }
      
    • 两个非负数字:则分别视为 flex-growflex-shrink的值,flex-basis0%,等同于:

      .item{ flex: 2 3; }
      .item {
          flex-grow: 2; /*第一个非负数字*/
          flex-shrink: 3; /*第二个非负数字*/
          flex-basis: 0%; 
      }
      
    • 一个非负数字,一个长度或百分比:则分别视为 flex-growflex-basis 的值,flex-shrink1,等同于:

      .item{ flex: 2333 3222px; }
      .item {
          flex-grow: 2333; /*非负数字*/
          flex-shrink: 1; 
          flex-basis: 3222px; /*一个长度或百分比*/
      }
      

    2.4 例子

    例1:设置父元素width=600px,三个子元素A、B、C,A的width为140px,flex为2 1 0%,B的width为100px,flex为2 1 auto,C不设width,flex为1 1 200px。求A、B、C三个元素的width是多少?

    <div class="box">
            <div class="item_1">A</div>
            <div class="item_2">B</div>
            <div class="item_3">C</div>
    </div>
    
    .box {
        width: 600px;
        border: 1px solid black;
        margin: 100px auto;
        display: flex;
    }
    .box>div {
        height: 100px;
    }
    .item_1 {
        width: 140px;
        flex: 2 1 0%;
        background-color: slateblue;
    }
    .item_2 {
        width: 100px;
        flex: 2 1 auto;
        background-color: teal;
    }
    .item_3 {
        flex: 1 1 200px;
        background-color: skyblue;
    }
    
    显示结果

    计算过程:

    • 主轴上的父容器总尺寸为600px
    • 子元素的总基准值:0% + auto + 200px = 300px,其中
      • 0%即0宽度
      • auto对应取主尺寸 即100px(B元素的宽度)
    • 伸缩放大系数之和:2 + 2 + 1 = 5
    • 剩余空间为600px - 300px = 300px , 剩余空间分配:
      • A和B各分配 2/5,即各得120px
      • C分配1/5,得60px
    • 最终各个元素的宽度分别为
      • A的宽度 = 0%(0px) + 120px = 120px
        当A的基准值取0%时,是把该元素当作零尺寸的,所有即使声明width为140px,也没有用
      • B的宽度 = auto(100px) + 120px = 220px
        当B的基准值取auto时,根据规则基准值使用值是主尺寸值即 100px(B的width),所以这100px不会纳入剩余空间
      • C的宽度 = 200px + 60px = 260px

    例2:设置父元素width=600px,三个子元素A、B、C,A的width为140px,B的width为100px,C不设width,flex均为auto。求A、B、C三个元素的width是多少?

    <div class="box">
            <div class="item_1">A</div>
            <div class="item_2">B</div>
            <div class="item_3">C</div>
    </div>
    
    .box {
        width: 600px;
        border: 1px solid black;
        margin: 100px auto;
        display: flex;
    }
    .box>div {
        height: 100px;
    }
    .item_1 {
        width: 140px;
        flex: auto;
        background-color: slateblue;
    }
    .item_2 {
        width: 100px;
        flex: auto;
        background-color: teal;
    }
    .item_3 {
        flex: auto;
        background-color: skyblue;
    }
    
    每个元素都设置为flex:auto的情况

    计算过程:

    • 主轴上的父容器总尺寸为600px
    • 子元素的总基准值:auto + auto + auto = 240px,其中
      • auto取得各个元素的width值
        • A元素的auto 为 140px
        • B元素的auto 为 100px
        • C元素的auto 为 0
    • 伸缩放大系数之和:1 + 1 + 1 = 3
      • auto 表示为 1 1 auto
    • 剩余空间为600px - 240px = 360px , 剩余空间分配:
      • A、B、C各分配 1/3,即各得120px
    • 最终各个元素的宽度分别为
      • A的宽度 = auto(140px) + 120px = 260px
      • B的宽度 = auto(100px) + 120px = 220px
      • C的宽度 = auto(0px) + 120px = 120px

    例3:设置父元素width=600px,三个子元素A、B、C,A的width为140px,B的width为100px,C不设width,flex均为1。求A、B、C三个元素的width是多少?

    <div class="box">
            <div class="item_1">A</div>
            <div class="item_2">B</div>
            <div class="item_3">C</div>
    </div>
    
    .box {
        width: 600px;
        border: 1px solid black;
        margin: 100px auto;
        display: flex;
    }
    .box>div {
        height: 100px;
    }
    .item_1 {
        width: 140px;
        flex: 1;
        background-color: slateblue;
    }
    .item_2 {
        width: 100px;
        flex: 1;
        background-color: teal;
    }
    .item_3 {
        flex: 1;
        background-color: skyblue;
    }
    
    flex:1的情况

    计算过程:

    • 主轴上的父容器总尺寸为600px
    • 子元素的总基准值:0% + 0% + 0% = 0px,其中
      • 0%即0px
    • 伸缩放大系数之和:1 + 1 + 1 = 3
      • flex : 1 表示为 1 1 0%
    • 剩余空间为600px - 0px = 600px , 剩余空间分配:
      • A、B、C各分配 1/3,即各得200px
    • 最终各个元素的宽度分别为
      • A的宽度 = 0%(0px) + 200px = 200px
      • B的宽度 = 0%(0px) + 200px = 200px
      • C的宽度 = 0%(0px) + 200px = 200px

    2.5 参考文章

    相关文章

      网友评论

          本文标题:flex:1及flex取值的理解

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