Code前端首页关于Code前端联系我们

css实例学习:深入理解 flex 属性如何控制布局效果

terry 2年前 (2023-09-27) 阅读数 63 #数据结构与算法
CSS案例分析:深入理解Flex属性如何控制布局效果其实Flex布局中有很多小细节。本文从示例角度分析Flex布局中的常用属性如何控制布局效果。

flex

flex flex参数用于控制flex元素在主轴上的宽度分布,主要由以下参数决定:

  • flex-grow:子元素不占用时如何增长所有空间
  • 弯曲 -shink:子元素如何在超出宽度时收缩
  • 弯曲? -basis:子元素初始宽度

flex-grow

当容器设置为flex-layout时,子元素会在主轴上排成一排。当子元素的总宽度小于容器时,可以设置flex-grow:非零值,子元素会增长宽度以填充容器。例如:

<html>
    <style>
        .container{
            display: flex;
            width: 600px;
            flex-wrap: no-wrap;
            border: 5px dashed slategrey;
        }
        .items{
            border-radius: 5px;
            text-align: center;
            font-size: 2em;
            color: white;
            flex-grow: 0;
        }
        .items:nth-child(1){
            background-color: darkgray;
            width: 100px;
        }
        .items:nth-child(2){
            background-color: aquamarine;
            width: 100px;
        }
        .items:nth-child(3){
            background-color: cadetblue;
            width: 100px;
        }
    </style>
    <body>
        <div class="container">
            <div class="items">1</div>
            <div class="items">2</div>
            <div class="items">3</div>
        </div>
    </body>
</html>

设置container-width为600px,每个子元素的宽度为100px并设置flex-grow:0,这次子元素将不会没有增长,效果是:

css实例学习:深入理解 flex 属性如何控制布局效果

当我们为每个子元素设置 flex-grow: 1 时,子元素会拉伸以填充子元素:

css实例学习:深入理解 flex 属性如何控制布局效果

当然,对于不同的子元素设置不同value 和 value 每个 子元素 的伸长量都会按照 flex-grow 进行分配。例如,对于三个子元素s,设置1 2 1,效果为:

css实例学习:深入理解 flex 属性如何控制布局效果

三个子元素的宽度为175 250 175,计算逻辑为:

剩余宽度 = 600 - 100 * 3 = 600 - 300 = 300

第1, 3个子元素增长宽度 = 1 / (1 + 2 + 1) * 300 = 1/4 * 300 = 75
第 2 个子元素增长宽度 = 2 / (1 + 2 + 1) * 300 = 1/2 * 300 = 150

因此最终宽度为:
100 + 75 = 175
100 + 150 = 250
100 + 75 = 175

flex-shink

当子元素的宽度不是时够了,可以拉伸。同样,当子元素的宽度超过容器时,也可以延长。可以收缩,控制flex-shink。将父元素的宽度更改为400px,将每个元素的宽度更改为200px。 子元素 的总宽度超过了父元素集合flex-shink: 0 观察不收缩的情况:

<html>
    <style>
        .container{
            display: flex;
            width: 400px;
            flex-wrap: no-wrap;
            border: 5px dashed slategrey;
        }
        .items{
            border-radius: 5px;
            text-align: center;
            font-size: 2em;
            color: white;
            flex-shrink: 0;
        }
        .items:nth-child(1){
            background-color: darkgray;
            width: 200px;
        }
        .items:nth-child(2){
            background-color: aquamarine;
            width: 200px;
        }
        .items:nth-child(3){
            background-color: cadetblue;
            width: 200px;
        }
    </style>
    <body>
        <div class="container">
            <div class="items">1</div>
            <div class="items">2</div>
            <div class="items">3</div>
        </div>
    </body>
</html>

css实例学习:深入理解 flex 属性如何控制布局效果 可以看到第三个子元素超过了父容器,目前设置的flex为每个 子元素 - shink : 1:

css实例学习:深入理解 flex 属性如何控制布局效果

可以看出,每个 子元素 都缩小以匹配父组件的宽度。当然,flex-shink也可以针对不同的子元素设置不同的值,然后按比例减少。例如设置为1 2 1:

css实例学习:深入理解 flex 属性如何控制布局效果

计算方法与flex-grow类似:

超出 = 400 - 200 * 3 = -200

第1, 3个子元素收缩(负增长)宽度 = 1 / (1 + 2 + 1) * 300 = 1/4 * -200 = -50
第 2 个子元素收缩(负增长)宽度 = 2 / (1 + 2 + 1) * 300 = 1/2 * -200 = -100

因此最终宽度为:
200 - 50 = 150
200 - 200 = 100
200 - 50 = 150

flex-basis

都是根据容器宽度和子元素的来增长和收缩初始宽度。事实上,初始宽度是由flex-basis决定的。上面的例子中,我们设置了宽度,但最终真正起作用的是flex-basis。常用的flex值有:

  • auto:如果子元素设置了width,那就是width。否则,这是子元素最大的内容
  • 宽度值:指定宽度值将覆盖宽度

。我们可以看到,如果子元素既没有指定width,也没有指定flex-basis,那么子元素的初始宽度就是max-length。最大长度是多少?看一下下面的例子:

<html>
    <body>
        <div style="width: 100px; border: 2px dashed;">
            <div style="width: max-content; border: 1px solid;">helo world 123 123 123</div>
            <div style="border: 1px solid;">helo world 123 123 123</div>
        </div>
    </body>
</html>

css实例学习:深入理解 flex 属性如何控制布局效果

我们可以看到,如果子元素没有提供宽度,则不会超过父元素的宽度。但是,当指定width: max-content时,子元素会根据最长宽度来计算,直接超过父容器。

我们只保留第一个子元素,并将flex-shink设置为0以表示不收缩。效果是:

css实例学习:深入理解 flex 属性如何控制布局效果

可以看到表现得像最大内容的宽度。

flex-basis = 0

flex-basis 设置为0时,相当于将子元素的宽度设置为0。此时,增长和收缩是相同的。例如,当我们固定子元素的宽度并对其进行扩展或缩小时,子元素的最终宽度并不完全是与flex-grow 成比例的,因为它会考虑到flex-basis 的计算中。当没有指定子元素的宽度,但我们希望严格按照flex-grow来划分他的宽度时,我们可以设置flex-basis:0。 ?子元素的纬度不同。但如果此时我们希望三个元素的宽度严格为1:1:1,我们可以设置 flex-grow:0,效果为:

css实例学习:深入理解 flex 属性如何控制布局效果

flex-wrap

人们常说Flex是一维布局。事实上,flex也可以处理一些简单的二维布局。如果设置了flex-wrap:wrap,如果字段宽度超过父容器,则剩余字段将换行显示。同时,设置flex-wrap:wrap也会影响flex-shrink,如下:

  1. 如果多个子元素s的宽度之和超过父容器,但没有元素带有a宽度大于父容器容器。此时 Flex Shrink 设置不起作用。因为超过父容器宽度的元素会被包裹。
  2. 如果给定的子元素的宽度超过父容器,那么如果该元素设置为flex-shrink:非零值,它将收缩以适合父容器,否则会溢出直接父容器。

例如父元素宽度设置为500像素,三个子元素的宽度为200像素,设置flex-wrap:0,则显示效果为:

css实例学习:深入理解 flex 属性如何控制布局效果

可以看到第三个元素超出了其父容器的宽度,因此换行显示。在此期间,这些元素不会缩小以适应父容器。

此时flex-grow仍然有效。逻辑是具有初始宽度且可以位于同一行的元素将拉伸以匹配父容器的宽度。为每个 子元素 设置 flex-grow:1。效果是:

css实例学习:深入理解 flex 属性如何控制布局效果

通过这个函数我们可以写出九个方格的网格布局:

<html>
    <style>
        .container{
            display: flex;
            width: 9rem;
            border: 5px dashed slategrey;
            flex-wrap: wrap;
        }
        .items{
            border-radius: 5px;
            text-align: center;
            font-size: 2em;
            color: white;
            flex: 0 0 3rem;
        }
        .items:nth-child(2n + 1){
            background-color: darkgray;
        }
        .items:nth-child(2n){
            background-color: aquamarine;
        }
    </style>
    <body>
        <div class="container">
            <div class="items">1</div>
            <div class="items">2</div>
            <div class="items">3</div>
            <div class="items">4</div>
            <div class="items">5</div>
            <div class="items">6</div>
            <div class="items">7</div>
            <div class="items">8</div>
            <div class="items">9</div>
        </div>
        
    </body>
</html>

css实例学习:深入理解 flex 属性如何控制布局效果

总结

  1. flex-grow:当子元素的初始长度为总和小于父容器时,如何拉伸以适合父容器
  2. flex -shrink:当子元素的初始长度后来大于父容器时,如何收缩以适应父容器
  3. flex-basis:控制子元素的初始长度子元素。
    1. 汽车:如果子元素指定了宽度,这就是宽度。否则是 max-content
    2. 的固定值,相当于设置 widtht 为这个值
    3. 设置这个值会覆盖 子元素 的宽度
  4. flex-wrap:当 子元素 的初始长度为比父容器大,子元素不会收缩,没有这是直接换行

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

热门