flex实现三栏布局原理

时间:2024-11-16 18:35:39

这里写图片描述

<style>
    .flex-box{
       display: flex;
       height:200px;
       width:100%;
       background:red;
     }

     .item:nth-child(2){
       flex:1;
       background:red;
     }
    </style>

    <div class="flex-box">
        <div class="item" style="width:200px;background:yellow"></div>
        <div class="item"></div>
        <div class="item"  style="width:200px;background:yellow"></div>
    </div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

关键在于:flex:1;这个属性

我们展开看一下这个属性:
这里写图片描述

要明白这个三栏布局的原理,其实就是要弄懂flex-growflex-shrinkflex-basis 三个属性的含义;

flex-grow
属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。

这里重点是理解这个剩余空间的含义:

我举个例子了解一下:

     <style>
       .flex-box{
             display: flex;
             height:200px;
             width:500px;
             background:red;
        }

        .left{
             width:100px;
             background:yellow;
        }

        .right{
             flex-grow:1;
             background:yellow;
        }
        .center{
             flex-grow:1;
             background:red;
        }
    </style>

    <div class="flex-box">
        <div class="left">
            left
        </div>
        <div class="center">
            center
        </div>
        <div class="right">
            right
        </div>
    </div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

整个flex容器大小我设置的为500px,我只给left设置了100px,那么我们剩余的空间的大小就为500-100-48-40=312px(为什么要减去48和40呢?因为我们的'center和'right'文本也占了空间);
剩下的这312px就由具有flex-grow属性的元素去分(left没有设置该属性,默认为0),也就是我们的center和right去分,分的依据就是flex-grow的值,它们的值分别为1,代表着各占剩余空间的一份,那么就是156px,最后再加上各自本身占的空间,center为48+156=204px;right为40+156=196px;

flex-shrink
属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。

    <style>
        .flex-box{
          display: flex;
          height:200px;
          width:400px;
          background:red;
        }

        .left{
            width:300px;
            flex-shrink:1;
            background:yellow;
        }

        .center{
            width:160px;
            flex-shrink:2;
            background:red;
        }

        .right{
            width:140px;
            flex-shrink:3;
            background:yellow;
        }
    </style>

    <div class="flex-box">
        <div class="left">
            left
        </div>
        <div class="center">
            center
        </div>
        <div class="right">
            right
        </div>
    </div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

这里写图片描述

整个容器大小为400px,left,center,right宽度分别为200px,160px,140px按照这个数据算下来,父容器的空间是不够的,不考虑换行的情况下,我们需要利用到flex-shrink这个属性,使得我们的内容按照一定的比例进行缩小;
首先算出溢出空间:400-200-160-140=-200px,溢出的200px需要按照一定的比例分配给left,center,right;由于它们的flex-shrink分别为1,2,3;我们设left为缩小比例为x,那么center,right则为2x,3x;
根据等式200x+160*2x+140*3x=200
我们求出x=5/26;
最后根据这个缩小比例,分别求出left,center,right真实大小:
left:200*(1-5/26) =242.31 px
center:160*(1-5/26*2) =98.47 px
right:140*(1-5/26*3) = 59.23 px

flex-basis
属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。

简单的说这个属性值可以理解为元素的width值;
如果flex-basis和width其中有一个是auto,那么另外一个非auto的属性优先级会更高。同时赋值时,flex-basis的优先级更高


介绍完了三个属性,我们再回过头来看flex实现三栏布局的原理
这里写图片描述

我们left和right设置了固定的宽度,然后将flex-basis设置为0,使得容器的剩余空间仅为容器总宽度减去left和right的宽度,不减去center本身内容的宽度,这里可以借鉴一下上面说的flex-grow属性中,我们的剩余空间是包括减去自身内容宽度后的宽度;

然后设置flex-growflex-shrink设置为1,将剩余的宽度全部分配给自己,不管宽度是有剩余还是溢出,也达到了自适应的要求