V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
awesomePower
V2EX  ›  程序员

前端求教,有没有懂 flex 布局的

  •  
  •   awesomePower · 110 天前 · 2927 次点击
    这是一个创建于 110 天前的主题,其中的信息可能已经有所发展或是发生改变。

    是这样的,给flex容器设置了align-content: stretch;,它也是个默认值,有拉伸的效果。

    然后所有子项中有一个设置了高度,最后拉伸的结果是两行的高度不一样,它是怎么个原理,每行最终的拉伸高度是怎么计算的,有大佬给解答一下吗?

    代码示例: https://txgq4v-5000.csb.app/

    28 条回复    2024-01-13 11:05:27 +08:00
    awesomePower
        2
    awesomePower  
    OP
       110 天前
    @fd9xr 上面只写了拉伸占据剩余空间。没写拉伸的幅度是怎么计算的啊。我想知道多行、高度和没设置高度混合的情况下,拉伸的空间是怎么计算的
    xiaoqidev
        3
    xiaoqidev  
       110 天前   ❤️ 2
    容器高 500 ,p 有默认边距行高等,div 默认高度大概 120 ,3 指定高度 190 ,剩余空间 500-120-190=190 默认拉伸 1:1 分配各 95 ,1 、2 高 120+95 约 215 ,3 指定高 190 ,4 高跟 3 一样 190 再加拉伸 95 最后高 285
    awesomePower
        4
    awesomePower  
    OP
       110 天前
    @xiaoqidev 谢谢你的解答,很详细。我有两个疑问:

    1.div 的这里默认高度为什么是 120 呢

    2. 4 和 3 的高度一样的原因是不是因为 align-items 的默认属性也是拉伸,导致 4 拉伸成了行高
    awesomePower
        5
    awesomePower  
    OP
       110 天前
    @xiaoqidev 我看了一下 chrome 的盒模型示意图,懂了。这里因为字体设置的原因,导致 p 元素的高度是 49 ,然后又因为 font-size:35px;导致 p 的 margin-top 和 margin-bottom 也是 35px ,最后加起来就是 49+35+35=119 。

    再次感谢你的解惑
    c9y
        7
    c9y  
       110 天前   ❤️ 1
    我是这么理解的.
    你这个例子中:
    结构 .box > (.item > p)*4, p 的 font-size: 35px, line-height 和 margin 为浏览器默认
    我这里使用 chrome, 默认 line-height: 1.4, margin: font-size 0; (这里非常要注意浏览器的默认属性, 尤其是 line-height, 比如 mdn 就说明了大部分是默认 1.2, 这里使用 1.4 是使用了你提供的, 实际上我进入你的页面 font-size*line-height = 46, 这里 line-height 是无穷小数, 所以一般需要严格计算的地方应该指定 line-height)
    即: p 的高度为 margin-top + (font-size * line-height) + margin-bottom = 35px + (35px * 1.4) + 35px = 119px
    第 2 行的一个.item 设置了 height: 190px, 其他.item 的 height 自适应
    假设: 第 1 行自适应高度为 x, 第 2 行自适应高度为 y.
    则有: y - x = 190px - 119px = 71px (这个是重点, 会根据可以用于计算的值用于计算占比)
    x + y = 500px
    两式相加: 2y = 500px + 71px, y = 285.5px
    则 x = 214.5px.
    c9y
        8
    c9y  
       110 天前
    @c9y #7 y - x = 190px - 119px = 71px
    (编辑的时候把 71px 干掉了
    c9y
        9
    c9y  
       110 天前
    @c9y #8 好吧, 是有问题. 不知道为啥 v2 自己干掉了
    awesomePower
        10
    awesomePower  
    OP
       110 天前
    @c9y 谢谢大佬的详细回答。我之前不知道 line-height 还有这些知识点。另外问一下,为什么 margin-top 和 font-size 一样是 35px 呢
    c9y
        11
    c9y  
       110 天前
    @awesomePower #10 也是浏览器的默认行为吧, 估计是 margin: 1em 0;
    一般除非写 blog 文章, 不然的话, 默认的 css 都是不可靠了
    gowk
        12
    gowk  
       110 天前   ❤️ 5
    https://flexboxfroggy.com/
    照着这个网站练习一遍就会了
    NoManPlay
        13
    NoManPlay  
       110 天前   ❤️ 1
    @awesomePower #10
    这个 user agent stylesheet 是浏览器默认行为,不同浏览器效果不一样。
    1em 是当前对象内文本的字体尺寸,所以 margin-top 和 font-size 一样,比如你设置别的 div 字体为 16 ,那么单独那一个 div 的 margin-top 就变成 16 了
    awesomePower
        14
    awesomePower  
    OP
       110 天前
    @c9y 原来是这样,谢谢解答
    awesomePower
        15
    awesomePower  
    OP
       110 天前
    @gowk 谢谢分享!宝藏网站,这个简直太有帮助了
    awesomePower
        16
    awesomePower  
    OP
       110 天前
    @NoManPlay 我在我这边的浏览器找了下,也是这个默认值值,怪不得是 35px 。谢谢你的帮助。
    jisuowei
        17
    jisuowei  
       110 天前
    blankmiss
        18
    blankmiss  
       110 天前
    crazyTanuki
        19
    crazyTanuki  
       110 天前
    awesomePower
        20
    awesomePower  
    OP
       110 天前
    wweerrgtc
        21
    wweerrgtc  
       110 天前
    @gowk 花了 20 分钟通关了😂
    ChrisFreeMan
        22
    ChrisFreeMan  
       109 天前
    @gowk 谢谢你,煤炭球画家
    gowk
        23
    gowk  
       109 天前
    @wweerrgtc #21 最后一个不会 😄
    a132811
        24
    a132811  
       109 天前
    你的例子中:分上下两个 flex row. 在 chrome version 120 下:

    第一个 row ,最大的 block 身高= 35px*1.15 + margin(70px) = 110px
    第二个 row ,最大的 block 身高= 190px

    纵轴剩余: 500px - 110px - 190px = 200px, 两者平分各 100px 。

    第一个 row:110+100 = 210px
    第二个 row:190+100 = 290px (强制指定 item 的 190px 则不受影响)

    ---------
    BTW ,这个类似主轴分配规则,比如:

    ```html
    <div style="width:400px;display:flex">
    <div style="width:100px;flex-grow:1">item-a</div>
    <div style="width:100px;flex-grow:2">item-b</div>
    </div>
    item-a, item-b 会根据 flex-grow 值,分割剩余的 200px(仅当存在剩余空间时)
    item-a: 100 + 200px*(1/3) = 166.66
    item-b: 100 + 200px*(2/3) = 233.33
    ```
    a132811
        25
    a132811  
       109 天前
    @a132811 chrome version 120 默认 line-height 1.15
    a132811
        26
    a132811  
       109 天前
    awesomePower
        27
    awesomePower  
    OP
       109 天前
    @a132811 感谢解答和分享
    gowk
        28
    gowk  
       105 天前
    @gowk #23
    记录一下最后一题:
    flex-flow: column-reverse wrap-reverse;
    align-content: space-between;
    justify-content: center;
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2670 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 10:50 · PVG 18:50 · LAX 03:50 · JFK 06:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.