zoukankan      html  css  js  c++  java
  • Finally! I do understand "flex-basis"

    Long, long, long ago,CSS3就支持了flex布局,现在各家浏览器都支持标准的语法了,这里推荐一篇比较全面的图文化教程A Complete Guide to Flexbox.

    关于Flex布局,刚开始学习CSS的时候就"复习"了好几遍,不是我吹,下面的代码也是信手拈来.

    div {
        display: flex;
        justify-content: space-evenly;
        align-items: center;
    }
    

    but,but,but.....,

    flex布局的伸缩子项上支持一个叫做flex-basis的属性.阅文档无数,我还是从始至终都没怎么理解.最近在写自己的博客主题mweb-mine的时候抄了一个样式flex: 1 1 300px让我重新想起了flex-basis这个妖精,所以我决定这次一定要收了它.

    MDN:flex-basisMDN文档对于此属性的解释如下

    The flex-basis CSS property sets the initial main size of a flex item. It sets the size of the content box unless otherwise set with box-sizing.

    翻译过来就是:

    CSS 属性 flex-basis 指定了 flex子项元素在主轴方向上的初始大小。如果不使用 box-sizing 来改变盒模型的话,那么这个属性就决定了 flex 子项元素的内容盒(content-box)的宽或者高(取决于主轴的方向)的尺寸大小。

    读罢此句,似乎也不知道flex-basis是用来干什么的,有人对这个属性的使用进行了总结,下面的两句是我认为最精华的两点:

    1.flex-basis allows you to specify the initial/starting size of the element, before anything else is computed. It can either be a percentage or an absolute value.
    flex-basis允许您在计算任何其他内容之前指定元素的初始/开始大小。它可以是百分比,也可以是绝对值。
    2.flex-basis defines the default size of an element before the remaining space is distributed. It can be a length (e.g. 20%, 5rem, etc.) or a keyword.
    flex-basis定义在分配剩余空间之前元素的默认大小。它可以是一个长度(例如20%,5rem等)或关键字

    也许上面的解释还是比较难懂,下面我们结合w3c的wiki文档中提供的一张图来说明

    我们都知道,flex布局的最大的特点就是可以自定义如何分配容器剩余的空间,或者压缩子项来适应空间的不足.扩展比率是由flex-grow设置的,收缩比率是由flex-shrink设置的,伸缩基准是由flex-basis设置的,三个属性合并的写法就是flex属性.如上图,假设一个场景,伸缩容器的宽度是1000px,伸缩子项item1,item2,item3的width分别是100px,400px;200px.

    <div id="container">
      <div class="item1"></div>
      <div class="item2"></div>
      <div class="item3"></div>
    </div>
    
    div {
      box-sizing: border-box;
    }
    
    #container {
      display: flex;
      box-sizing: content-box;
      margin: auto;
       1000px;
      height: 200px;
      border: 2px solid orange;
      font-size: 1.5rem;
      color: white;
    }
    
    .item1 {
       100px;
      background: red;
    }
    .item2 {
       300px;
      background: green;
    }
    .item3 {
       200px;
      background: blue;
    }
    

    子项的flex属性默认值为flex: 0 1 auto,即有剩余空间时也不进行扩展,因此其默认的显示如上图.容器右侧剩余400px的空间.接下来,我们给子项添加上扩展比率flex-grow,让子项按照1:1:2的比率分配剩余空间.

    .item{
      flex-basis: auto;
    }
    
    .item1{
       100px;
      flex-grow: 1;
      background: red;
    }
    .item2{
       300px;
      flex-grow: 1;
      background: green;
    
    }
    .item3{
       200px;
      flex-grow: 2;
      background: blue;
    }
    

    上述伸缩基准flex-basis: auto,这个值会在浏览器分配空间时计算为元素在主轴方向上的长度属性,此例子中即为子项的宽度.从上图可以看出,剩余空间按照100px: 100px: 200px分别分配给了子项,子项在原有width值上进行了这些叠加.这似乎符合我们常用的习惯,接下来,我们修改一处地方,将所有子项的伸缩基准设置为flex-basis: 0

    .item{
      flex-basis: auto;
    }
    


    从上图可以看出实际展示宽度发生了天翻地覆的变化,我们来分析一下这个变化的原因.还记得文章一开始的重点吗:
    flex-basis定义在分配剩余空间之前元素的默认大小

    也就是说,当所有子项设置flex-basis: 0,在分配空间的时候浏览器不再关注所有子项原有的宽度(准确的说是:子项在主轴方向的长度),这时剩余宽度就是1000px - 0px -0px -0px = 1000px,然后直接按照1:1:2的比例分配1000px,所以最终三个子项的宽度分别为: 200px, 200px, 400px.

    有一个很形象的例子可以解释上述空间的分配,解放初期,我国进行过"人民公社化"的尝试,假设有一个公社有三户人家,三家各有粮食100kg, 300kg, 200kg,三家各有1,1,2口人,各家各户把家里的余粮全部上交到公社食堂,县里又给公社拨了400kg粮食,这样各家的余粮都是0,公社共有1000kg的粮食,在食堂吃饭的时候,是按照各户人口来分配食物的,所以三家分到的食物分别是200kg, 200kg, 400kg

    有了上面的准则和介绍,下面的变化应该就能分析出来了.

    .item1 {
       100px;
      flex-grow: 1;
      flex-basis: 200px;
      background: red;
    }
    .item2 {
       300px;
      flex-grow: 1;
      flex-basis: 100px;
      background: green;
    }
    .item3 {
       200px;
      flex-grow: 2;
      flex-basis: 300px;
      background: blue;
    }
    

    在分配空间的时候,子项在主轴上的基准长度,由flex-basis决定,也就是200px, 100px, 300px,剩余400px按照1:1:2的比例分配,最后宽度200px+100px=300px, 100px+100px=200px, 300px+200px=500px

    最后还有两点需要注意:
    1.flex-basis影响的子项在主轴上的伸缩基准值,前面的例子我们默认的flex-direction: row,如果flex-direction: column也有学会以此类推.空间不足的时候子项需要的收缩情况也可以类比出来.

    2.需要注意子项的长度还是会受到max-width/min-width(当flex-direction: row)或max-height/min-height的影响,比如给最后一项添加一个max-400px

    .item1 {
       100px;
      flex-grow: 1;
      flex-basis: 200px;
      background: red;
    }
    .item2 {
       300px;
      flex-grow: 1;
      flex-basis: 100px;
      background: green;
    }
    .item3 {
      max- 400px;
       200px;
      flex-grow: 2;
      flex-basis: 300px;
      background: blue;
    }
    


    因为第三项的最大长度是400px,那就多出来100px,前面两项按照1:1分配掉

    参考:
    What are the differences between flex-basis and width?
    Css3-flexbox/zh-hans
    The Difference Between Width and Flex Basis

  • 相关阅读:
    HDOJ 1015 Safecracker
    POJ3187 虽然超时了,但是还得纪念一下
    HDOJ 1248
    HDOJ 1161
    动态规划——砝码称重
    P01P02P03各种背包!!
    对基类与派生类对象和指针赋值的小结
    程序员技术练级攻略
    CodeForces 愚人节题目
    java入门
  • 原文地址:https://www.cnblogs.com/star91/p/Finally-I-do-understand-flexbasis.html
Copyright © 2011-2022 走看看