当孩子依赖父母,父母依赖孩子时,浏览器如何计算宽度
Posted
技术标签:
【中文标题】当孩子依赖父母,父母依赖孩子时,浏览器如何计算宽度【英文标题】:How do browsers calculate width when child depends on parent, and parent's depends on child's 【发布时间】:2020-11-10 02:07:06 【问题描述】:我在我的 React 应用程序中遇到了各种故障、奇怪的渲染工件等等,我想知道从浏览器的角度定义维度的工作方式。
假设我有一个网格显示,有一个 div
具有 grid-template-columns: 1fr auto 1fr
和一个子 div
具有跨度 grid-column: 2 / 3
- 换句话说,跨越父网格的 auto
区域。
据我了解,网格模板列中的值 auto
定义了要调整大小以适应其内容的列。
现在让我们添加一个img
并将max-width
设置为100%
- 换句话说,我们不想超过父容器的大小。
但是,父容器的宽度是由auto
规则决定的——那么浏览器如何让子容器知道占用100%呢?
例子
.box
display: grid;
grid-template-columns: 1fr auto 1fr;
background-color: lightblue;
.box>div
border: 1px solid red;
grid-column: 2 / 3;
margin: 10px 10px 0px;
<div class="box">
<div style="">
<img src="https://via.placeholder.com/800" style="max-width:100%">
</div>
</div>
【问题讨论】:
【参考方案1】:为了解释这一点,我将从一个更简化的示例开始,它会产生相同的输出:
<div style="display:inline-block">
<img src="https://via.placeholder.com/1000x100">
</div>
<div style="display:inline-block">
<img src="https://via.placeholder.com/1000x100" style="max-width:100%">
</div>
<div style="display:inline-block">
<!-- even a big explicit width specified won't change the behavior -->
<img src="https://via.placeholder.com/1000x100" style="wdith:2000px;max-width:100%">
</div>
<div style="display:inline-block">
<img src="https://via.placeholder.com/1000x100" style="width:100%">
</div>
我们有一个inline-block
元素,所以它的宽度取决于它的内容,使用max-width:100%
(或width:100%
)会给我们带来奇怪的结果。
要理解这一点,我们需要参考规范,更准确地说是Percentage Sizing 部分,我们可以阅读:
有时,百分比大小的盒子的包含块的大小取决于盒子本身的内在尺寸贡献,从而产生循环依赖 .当计算这样一个盒子的内在尺寸贡献时(包括任何基于内容的自动最小尺寸的计算),一个循环百分比 - 即一个百分比值,它将针对本身取决于该百分比的包含块大小进行解析 - 是特别解决:
我们的盒子是图片,包含块是inline-block
div。图片是替换元素,所以我们需要按照 (b) 和 (c) 来识别 最大内容贡献 和 最小内容贡献
b.同样,如果盒子被替换,那么任何最大尺寸属性或首选尺寸属性的整个值都被处理为包含循环百分比的表达式以计算盒子的最大内容贡献 仅作为该属性的初始值。
将max-width
/width
视为自动将保持最大内容贡献相同(在我们的例子中为1000px
)。将改变的是 min-content 贡献:
c。如果盒子被替换,任何最大尺寸属性或首选尺寸属性(width/max-width/height/max-height)的值中的循环百分比,在计算 min-content 贡献时解决为零对应的轴。
因此图像的最小内容贡献将变为0
,不再是1000px
,这是基于其内在维度的初始最小内容贡献(相关:https://www.w3.org/TR/css-sizing-3/#intrinsic-sizes),所有技巧都在这里!
现在我们的 inline-block 是一个收缩到适合的元素,下面的算法适用:
那么收缩到适合的宽度是:
min(max(preferred minimum width, available width), preferred width)
。 ref
图像的贡献从0
到1000px
不等,因此浏览器将选择避免任何溢出的值(可用宽度部分)并且不大于1000px
(min 部分)
如果不使用百分比,图像的最小内容为1000px
,因此浏览器必须使用1000px
和1000px
之间的值作为首选最小宽度 div 图像的固有尺寸宽度。
这一切只是div宽度的计算。在此之后,我们将计算出的宽度作为百分比值的参考。
我们也可以考虑不同的值,逻辑是一样的:
div
border:2px solid red;
margin:5px;
<div style="display:inline-block">
<img src="https://via.placeholder.com/1000x100">
</div>
<div style="display:inline-block">
<img src="https://via.placeholder.com/1000x100" style="max-width:80%">
</div>
<div style="display:inline-block">
<img src="https://via.placeholder.com/1000x100" style="width:50%">
</div>
上述逻辑以相同的方式应用于您的代码,因为您的列设置为auto
,这意味着它的大小取决于其内容,也是图像的包含块。
【讨论】:
既然你问了,这一切对我来说都是正确的,并且经过严格的覆盖。 是的,并且在 CSS2.1 中该行为是明确未定义的。:w3.org/TR/CSS2/visudet.html#x9 "如果包含块的宽度取决于此元素的宽度,则结果布局在 CSS 2.1 中未定义。"跨度>以上是关于当孩子依赖父母,父母依赖孩子时,浏览器如何计算宽度的主要内容,如果未能解决你的问题,请参考以下文章