Daily-Interview-Question icon indicating copy to clipboard operation
Daily-Interview-Question copied to clipboard

第 155 题:求最终 left、right 的宽度

Open yygmind opened this issue 4 years ago • 27 comments

<div class="container">
    <div class="left"></div>
    <div class="right"></div>
</div>

<style>
  * {
    padding: 0;
    margin: 0;
  }
  .container {
    width: 600px;
    height: 300px;
    display: flex;
  }
  .left {
    flex: 1 2 500px;
    background: red;
  }
  .right {
    flex: 2 1 400px;
    background: blue;
  }
</style>

yygmind avatar May 13 '20 01:05 yygmind

先分析flex属性的信息 1.left容器 放大比例1,缩小比例 2 默认占500px 2.right容器 放大比例2,缩小比例 1 默认占400px

当子项目宽度总和大于父容器宽度时,如果有缩小比例将按照缩小比例进行压缩,比如子项目总和900px大于父容器600px,多出的300px将按照缩小比例进行压缩 left容器将会压缩2/3* 300 = 200px right容器将会压缩1/3* 300 =100px 所以最终left和right宽度都是300px

同理当子项目宽度总和小于父容器宽度时,如果有放大比例将按照放大比例进行扩张。

浏览器跑一下吧,不是这个结果

mengsixing avatar May 13 '20 02:05 mengsixing

left 父元素:600px left:500px,shrink :2 right:400px,shrink :1 超了300px left = leftWidth - overWidth * (leftWidth * leftShrink / ( leftWidth * leftShrink + rightWidth * rightShrink)) left = 500 - 300 * (500 * 2/( 500 * 2 + 400 * 1)) = 285.714

JaniceDong avatar May 13 '20 02:05 JaniceDong

先分析flex属性的信息 1.left容器 放大比例1,缩小比例 2 默认占500px 2.right容器 放大比例2,缩小比例 1 默认占400px 当子项目宽度总和大于父容器宽度时,如果有缩小比例将按照缩小比例进行压缩,比如子项目总和900px大于父容器600px,多出的300px将按照缩小比例进行压缩 left容器将会压缩2/3* 300 = 200px right容器将会压缩1/3* 300 =100px 所以最终left和right宽度都是300px 同理当子项目宽度总和小于父容器宽度时,如果有放大比例将按照放大比例进行扩张。

浏览器跑一下吧,不是这个结果

跑了一下,确实不是这个结果,希望大佬给出正确的解析

whmk-m avatar May 13 '20 02:05 whmk-m

子元素的 flex-shrink 的值分别为 2,1 溢出:500+400 - 600 = 300。 总权重为 2 * 500+ 1 * 400 = 1400 两个元素分别收缩: 300 * 2(flex-shrink) * 500(width) / 1400= 214.28 300 * 1(flex-shrink) * 400(width) / 1400= 85.72 三个元素的最终宽度分别为: 500 - 214.28 = 285.72 400 - 85.72 = 314.28

timeyo avatar May 13 '20 02:05 timeyo

子元素的 flex-shrink 的值分别为 2,1 溢出:500+400 - 600 = 300。 总权重为 2 * 500+ 1 * 400 = 1400 两个元素分别收缩: 300 * 2(flex-shrink) * 500(width) / 1400= 214.28 300 * 1(flex-shrink) * 400(width) / 1400= 85.72 三个元素的最终宽度分别为: 500 - 214.28 = 285.72 400 - 85.72 = 214.28

最后一个是 314.28~哈哈哈

linsicong003 avatar May 13 '20 02:05 linsicong003

对应题目:

  • 子项溢出空间的宽度为 $500 + 400 - 600 = 300$
  • left 收缩比例:$(500 × 2) ÷ (500 × 2 + 400 × 1) ≈ 0.7143$
  • right 收缩比例:$(400 × 1) ÷ (500 × 2 + 400 × 1) ≈ 0.2857$

对应的:

  • left 收缩宽度:$0.7143 × 300 = 214.29$
  • right 收缩宽度:$0.2857 × 300 = 85.71$

所以:

  • left 最终宽度:$500 - 214.29 = 285.71$
  • right 最终宽度:$400 - 85.71 = 314.29$

Demo

hexuan-aurora avatar May 13 '20 04:05 hexuan-aurora

如果container的宽度是1000px, left 和 right 的宽度是怎么计算的?@timeyo @hexuan-aurora

moi-xiey avatar May 13 '20 06:05 moi-xiey

如果container的宽度是1000px, left 和 right 的宽度是怎么计算的?@timeyo @hexuan-aurora

子元素的 flex-grow的值分别为 1,2 剩余空间:1000 - 500+400= 100。 子元素所得到的多余空间分别为: 100 * 1 / 3= 33.33 100 * 2 / 3 = 66.67 子元素最终宽度分别为: 500 + 33.33 = 533.33 400 + 66.67 =466.67

timeyo avatar May 13 '20 06:05 timeyo

如果container的宽度是1000px, left 和 right 的宽度是怎么计算的?@timeyo @hexuan-aurora

子元素的 flex-grow的值分别为 1,2 剩余空间:1000 - 500+400= 100。 子元素所得到的多余空间分别为: 100 * 1 / 3= 33.33 100 * 2 / 3 = 66.67 子元素最终宽度分别为: 500 + 33.33 = 533.33 400 + 66.67 =466.67

谢谢答复, flex-grow 和 flex-shrink 的计算方式还不一样呢

moi-xiey avatar May 13 '20 06:05 moi-xiey

搜到一篇资料详细解释了flex-grow与flex-shrink。详解 flex-grow 与 flex-shrink

zhixinpeng avatar May 13 '20 07:05 zhixinpeng

溢出300=500+400-600; 溢出部分均分成14份,14=(52+41); (父元素不足分配时,取flex-shrink值,flex-basis值对应压缩) left收缩=300*(10/14); right收缩=300*(4/14); 减去收缩值,即最终长度。

wtt0561 avatar May 13 '20 07:05 wtt0561

@timeyo codepen 和我自己在页面内写里跑出来竟然都是 左300 右 300。。Chrome 81

image

image 那个是高度老哥。。。

hansonfang avatar May 29 '20 07:05 hansonfang

@hansonfang 哈哈哈哈眼拙了不好意思,谢啦谢啦!!

waynecz avatar Jun 09 '20 12:06 waynecz

<div class="container">
    <div class="left"></div>
    <div class="right"></div>
</div>

<style>
  * {
    padding: 0;
    margin: 0;
  }
  .container {
    width: 600px;
    height: 300px;
    display: flex;
  }
  .left {
    flex: 1 2 500px;
    padding: 20px;
    border: 2px solid blue;
    background: red;
  }
  .right {
    flex: 2 1 400px;
    padding: 50px;
    border: 1px solid red;
    background: blue;
  }
</style>

我也出道题

robynluo avatar Jun 12 '20 06:06 robynluo

image

image

image

上面题目的答案

robynluo avatar Jun 12 '20 06:06 robynluo

我是这样理解的:

left + right > container 则此时需要收缩 flex-shrink生效 left + right = container 收缩、扩张均失效 left + right < container 则此时需要扩张 flex-grow生效

收缩计算过程:

  • 1.计算收缩值:500 + 400 - 600 = 300
  • 2.计算总的收缩权重值:500 * 2 + 400 × 1 = 1400
  • 3.计算项目收缩空间:(项目宽度 - 项目宽度 × 总溢出空间 × flex-shrink / 总权重) left = 500 - 500 × 300 × 2 / 1400 ≈ 285.71 right = 400 - 400 × 300 × 1 / 1400 ≈ 314.28

扩张计算过程:

  • 1.计算扩张总内容 container - (left + right)
  • 2.计算每份扩张值:总内容/(left(flex-grow) + right(flex-grow))
  • 3.计算项目扩张大小:(项目宽度 + 每份扩张值 × 扩张系数(flex-grow))

syymo avatar Jul 03 '20 07:07 syymo

我是这样理解的:

left + right > container 则此时需要收缩,反正则需要扩张

收缩计算过程:

  • 1.计算收缩值:500 + 400 - 600 = 300
  • 2.计算总的收缩权重值:500 * 2 + 400 × 1 = 1400
  • 3.计算项目收缩空间:(项目宽度 - 项目宽度 × 总溢出空间 × flex-shrink / 总权重) left = 500 - 500 × 300 × 2 / 1400 ≈ 285.71 right = 400 - 400 × 300 × 1 / 1400 ≈ 314.28

扩张计算过程:

  • 1.计算扩张总内容 container - (left + right)
  • 2.计算每份扩张值:总内容/(left(flex-grow) + right(flex-grow))
  • 3.计算项目夸张大小:(项目宽度 + 每份扩张值 × 扩张系数(flex-grow))

应该是这样 //如果left + right = container,flex-grow和flex-shrink 失效;

jackchang2015 avatar Aug 04 '20 09:08 jackchang2015

子元素的 flex-shrink 的值分别为 2,1 溢出:500+400 - 600 = 300。 总权重为 2 * 500+ 1 * 400 = 1400 两个元素分别收缩: 300 * 2(flex-shrink) * 500(width) / 1400= 214.28 300 * 1(flex-shrink) * 400(width) / 1400= 85.72 三个元素的最终宽度分别为: 500 - 214.28 = 285.72 400 - 85.72 = 314.28

你们咋都这么厉害

yangchaojie456 avatar Aug 31 '20 09:08 yangchaojie456

left flex-basis=500 right flex-basis=400

容器总长度600 溢出长度(500+400)-600=300 加权factor综合为(5002+4001)=1400; 需要消化吸收的长度分别为: 500-(500:flex-basis*2:flex-shrink/1400)300:溢出宽度=285.71 400-(400:flex-basis1:flex-shrink/1400)*300:溢出宽度=314.29

zhangfytech avatar Sep 08 '20 06:09 zhangfytech

减小宽度计算公式

分配到的减小宽度 = 超出宽度 * (自身宽度 *(自身元素的 flex-shrink 值 / (所有子元素的 flex-shrink 值 * 自身宽度的和))

解题思路
flex: 1 2 500px;
// 等价于
flex-grow: 1;
flex-shrink: 2;
flex-basis: 500;

flex: 2 1 400px;
// 等价于
flex-grow: 2;
flex-shrink: 1;
flex-basis: 400;

因为 500 + 400 > 600,故需要使用 减小宽度计算公式

  • left 的宽度 = 500 - 300 * (500 * 2 / (500 * 2 + 1 * 400)) = 285.714
  • right 的宽度 = 400 - 300 * (400 * 1 / (500 * 2 + 1 * 400)) = 314.286

slogeor avatar Oct 12 '20 03:10 slogeor

专门看了一眼定义,感觉这是我们初中做题时都会遇到的坑,放大和缩小计算方式不同的根本原因是比例问题的基准值 flex-grow: 项目的放大比例,按照比例分配多余空间,这个按比例放大的基准值是多出来的空间,所以156题的解法大家都觉得没什么问题 相同的解法,这题的答案却不正确了 flex-shrink: 项目的缩小比例,空间不足时,项目按比例缩小,缩小之后的宽度为600px,比例的问题不能简单的反向计算 设:left的缩小比例是2x,right的缩小比例是x 则:500 * (1 - 2x) + 400 * (1 - x) = 600

解得:x = 300 / 1400

left = 500 * (1 - 2x) = 285.7px right = 400 * (1 - x) = 314.3px

这就是个初中就会遇到的的比例问题……大家要审题啊!

Luz-Liu avatar Feb 05 '21 09:02 Luz-Liu

专门看了一眼定义,感觉这是我们初中做题时都会遇到的坑,放大和缩小计算方式不同的根本原因是比例问题的_基准值_ flex-grow: 项目的放大比例,按照比例分配_多余空间_,这个按比例放大的基准值是多出来的空间,所以156题的解法大家都觉得没什么问题 相同的解法,这题的答案却不正确了 flex-shrink: 项目的缩小比例,空间不足时,项目按比例缩小,缩小之后的宽度为600px,比例的问题不能简单的反向计算 设:left的缩小比例是2x,right的缩小比例是x 则:500 * (1 - 2x) + 400 * (1 - x) = 600

解得:x = 300 / 1400

left = 500 * (1 - 2x) = 285.7px right = 400 * (1 - x) = 314.3px

这就是个初中就会遇到的的比例问题……大家要审题啊!

不错的角度,符合正常的逻辑

cescxu0712 avatar Feb 23 '21 15:02 cescxu0712

假如说有border以及padding,还需要考虑这些参数的影响,参考链接 填充和边框中的flex-shrink

ZHONGJIAFENG7 avatar Mar 15 '21 05:03 ZHONGJIAFENG7

先分析flex属性的信息 1.left容器 放大比例1,缩小比例 2 默认占500px 2.right容器 放大比例2,缩小比例 1 默认占400px 当子项目宽度总和大于父容器宽度时,如果有缩小比例将按照缩小比例进行压缩,比如子项目总和900px大于父容器600px,多出的300px将按照缩小比例进行压缩 left容器将会压缩2/3* 300 = 200px right容器将会压缩1/3* 300 =100px 所以最终left和right宽度都是300px 同理当子项目宽度总和小于父容器宽度时,如果有放大比例将按照放大比例进行扩张。

浏览器跑一下吧,不是这个结果

image

fygethub avatar Apr 07 '21 08:04 fygethub

专门看了一眼定义,感觉这是我们初中做题时都会遇到的坑,放大和缩小计算方式不同的根本原因是比例问题的_基准值_ flex-grow: 项目的放大比例,按照比例分配_多余空间_,这个按比例放大的基准值是多出来的空间,所以156题的解法大家都觉得没什么问题 相同的解法,这题的答案却不正确了 flex-shrink: 项目的缩小比例,空间不足时,项目按比例缩小,缩小之后的宽度为600px,比例的问题不能简单的反向计算 设:left的缩小比例是2x,right的缩小比例是x 则:500 * (1 - 2x) + 400 * (1 - x) = 600

解得:x = 300 / 1400

left = 500 * (1 - 2x) = 285.7px right = 400 * (1 - x) = 314.3px

这就是个初中就会遇到的的比例问题……大家要审题啊!

这个思路很棒!

mmmying avatar May 20 '21 02:05 mmmying

专门看了一眼定义,感觉这是我们初中做题时都会遇到的坑,放大和缩小计算方式不同的根本原因是比例问题的_基准值_ flex-grow: 项目的放大比例,按照比例分配_多余空间_,这个按比例放大的基准值是多出来的空间,所以156题的解法大家都觉得没什么问题 相同的解法,这题的答案却不正确了 flex-shrink: 项目的缩小比例,空间不足时,项目按比例缩小,缩小之后的宽度为600px,比例的问题不能简单的反向计算 设:left的缩小比例是2x,right的缩小比例是x 则:500 * (1 - 2x) + 400 * (1 - x) = 600

解得:x = 300 / 1400

left = 500 * (1 - 2x) = 285.7px right = 400 * (1 - x) = 314.3px

这就是个初中就会遇到的的比例问题……大家要审题啊!

由left = 500 * (1 - 2x) = 285.7px 可推导出left须缩小 300* 1000 / 1400=500-left; 由right = 400 * (1 - x) = 314.3px 可推导出right须缩小 300* 400 / 1400=400-right; 缩小时基准可为乘积的和,即500 * 2+400 * 1。

kklwoe avatar Aug 03 '21 08:08 kklwoe

总权重和 2 * 500+ 1 * 400 = 1400 溢出空间 500 + 400 - 600 = 300px 盒子宽度 = 默认宽度 - (盒子收缩权重/收缩总权重和) * 总溢出空间

left宽度 = 500px - (5002/1400) * 300 = 285.7px right宽度 = 400px - (4001/1400) * 300 = 314.3px

yumengbdw avatar Mar 07 '22 09:03 yumengbdw