css - 浏览器无法将相对单位(百分比)应用于fr设置的空间
问题描述
问题详情
我写了这样的代码。fr
在这里,由于width
、height
和object-fit
属性有效,图像应该被保留的空间传播。所以我认为第二个的文本.item
会溢出。
.container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr;
background: red;
gap: 10px;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="container">
<div class="item">
<img src="https://unsplash.it/450/450">
</div>
<div class="item">
<img src="https://unsplash.it/450/450">
text
</div>
</div>
在 Firefox 中,这会导致文本用完,
Chrome 并非如此。
此外,将图像包装在一个div
元素中而不是正好在网格项下方将解决问题。
.container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr;
background: red;
gap: 10px;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="container">
<div class="item">
<div class="content">
<img src="https://unsplash.it/450/450">
</div>
</div>
<div class="item">
<div class="content">
<img src="https://unsplash.it/450/450">
text
</div>
</div>
</div>
不相关但类似的文章
我发现了一个可能相关的问题,但我认为这个问题与我的问题无关,因为这个问题文本的源代码在 Firefox 和 Chrome 中可以正常工作。
- Chrome / Safari 未填充 flex 父级的 100% 高度
- 高度在 Chrome 和 Firefox 中呈现不同
- 在 flexbox 中使用 'height: 100%' 和 'align-items: stretch'
- 为什么我的 Grid 元素的高度计算不正确?
不相关但相似的错误
我还查找了相关的 bug 票,但这些票已经被声明为已修复,可能与我的问题无关。
- https://bugs.chromium.org/p/chromium/issues/detail?id=426898
- https://github.com/philipwalton/flexbugs/issues/197
问题
这种差异是没有错误票证或未定义行为的错误吗?
如果这不是未定义的行为,那么正确的行为是什么?
解决方案
如果这不是未定义的行为,那么正确的行为是什么?
我想说,Firefox 在这里做得正确,而 Chrome 是正确的。
首先,您可以将代码减少到以下内容,因为grid-template-rows: 1fr
该行为不需要
.container {
display: grid;
grid-template-columns: 1fr 1fr;
background: red;
gap: 10px;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="container">
<div class="item">
<img src="https://unsplash.it/450/450">
</div>
<div class="item">
<img src="https://unsplash.it/450/450">
text
</div>
</div>
然后您可以使用任何百分比值(小于或大于 100%),您将看到在我们有文本的第二种情况下,chrome 不会执行任何操作:
.container {
display: grid;
grid-template-columns: 1fr 1fr;
background: red;
gap: 10px;
}
img {
width: 100%;
height: 50%;
object-fit: cover;
}
<div class="container">
<div class="item">
<img src="https://unsplash.it/450/450">
</div>
<div class="item">
<img src="https://unsplash.it/450/450">
text
</div>
</div>
正如我在这里解释的那样,您正面临百分比高度的特定行为。默认情况下,百分比高度是相对于包含块的显式高度的,在我们的例子中,我们没有为行设置任何显式高度(1fr 不是显式的)。考虑到 CSS2 规范,我们应该不会auto
指定百分比高度。该百分比是相对于生成框的包含块的高度计算的。如果包含块的高度没有明确指定(即,它取决于内容高度),并且该元素不是绝对定位的,则该值计算为'auto'。 参考
Chrome 正在使用第二张图片执行此操作。它认为高度auto
不是完全错误的。
在 CSS3 规范中,我们有另一个部分允许浏览器做更多的工作:
有时,百分比大小的盒子的包含块的大小取决于盒子本身的内在大小贡献,从而产生循环依赖。当计算这样一个盒子的内在尺寸贡献时(包括任何基于内容的自动最小尺寸的计算),一个循环百分比 - 即一个百分比值,它将针对本身取决于该百分比的包含块大小进行解析 - 是特别解决:参考
然后你有一套复杂的规则,两个重要的部分是:
否则,百分比将根据包含块的大小进行解析。(包含块的大小不会根据框的结果大小重新解析;因此内容可能会溢出或下溢包含块)。
还有一条带有注释的规则:
注意:在这种情况下,网格项目和弹性项目确实允许解决百分比。
为方便起见,浏览器会先忽略百分比高度,根据内容计算每个网格轨道的高度,得到以下内容:
.container {
display: grid;
grid-template-columns: 1fr 1fr;
background: red;
gap: 10px;
}
img {
width: 100%;
/*height: 100%;*/
object-fit: cover;
}
<div class="container">
<div class="item">
<img src="https://unsplash.it/450/450">
</div>
<div class="item">
<img src="https://unsplash.it/450/450">
text
</div>
</div>
然后考虑先前计算的网格轨道高度,我们解决百分比高度得到以下结果,我们不再重新计算轨道高度:
.container {
display: grid;
grid-template-columns: 1fr 1fr;
background: red;
gap: 10px;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="container">
<div class="item">
<img src="https://unsplash.it/450/450">
</div>
<div class="item">
<img src="https://unsplash.it/450/450">
text
</div>
</div>
文本将在逻辑上溢出,因为高度是由图像+文本定义的,我们告诉图像获取所有高度,使文本在外部并使图像填充所有空间。
使用任何百分比值都会给出相同的结果,即使图像 X% 的高度由 image+text 定义。
设置显式高度将使两者的行为相同,因为我们没有复杂的计算,我们可以依赖规范的 CSS2 部分:
.container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows:200px;
background: red;
gap: 10px;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="container">
<div class="item">
<img src="https://unsplash.it/450/450">
</div>
<div class="item">
<img src="https://unsplash.it/450/450">
text
</div>
</div>
添加一个额外的包装器将使高度auto
在所有情况下都失败,因为浏览器处理这种情况变得更加复杂1。
.container {
display: grid;
grid-template-columns: 1fr 1fr;
background: red;
gap: 10px;
}
img {
width: 100%;
height: 958%;
object-fit: cover;
}
<div class="container">
<div class="item">
<div>
<img src="https://unsplash.it/450/450">
</div>
</div>
<div class="item">
<div>
<img src="https://unsplash.it/450/450">
</div>
text
</div>
</div>
添加height:100%
到额外的包装器将恢复到以前的情况,并且可以再次解决高度问题:
.container {
display: grid;
grid-template-columns: 1fr 1fr;
background: red;
gap: 10px;
}
img {
width: 100%;
height: 50%;
object-fit: cover;
}
.item>div {
height: 100%;
}
<div class="container">
<div class="item">
<div>
<img src="https://unsplash.it/450/450">
</div>
</div>
<div class="item">
<div>
<img src="https://unsplash.it/450/450">
</div>
text
</div>
</div>
在这种情况下,div 采用图像+文本定义的高度(文本将溢出),然后 div 内的图像将采用该高度的一半。
类似情况的相关问题:
https://stackoverflow.com/a/52137966/8620333
CSS Grid 中的 Chrome / Firefox 百分比高度差异
1:我无法给出确切的部分来解释为什么我们无法在这种情况下解决。
推荐阅读
- javascript - 店面功能未正确输出
- latex - 带有人物符号的 LaTeX 投影仪幻灯片
- java - 我想知道为什么这个结果不是 1000000
- php - Laravel: Eloquent Querybuilder whereTimestamp?
- go - 允许超过 content-type: application/json in gorilla
- java - 没有约束异常处理的休眠线程安全幂等插入?
- amazon-web-services - 使用 Route53、带缓存的 CloudFront、ELB 将 APEX 域重定向到子域
- r - R data.table 外连接与 roll="nearest" 有约束
- python - 迭代我的值的 2 个模型之间的 Django Queryset 过滤器对象?
- javascript - 为什么父自定义元素方法被覆盖?