【问题标题】:Setting the image `width: 0` hides it, while `width: 0%` makes it occupy the space, too设置图像 `width: 0` 隐藏它,而 `width: 0%` 使它也占据空间
【发布时间】:2026-01-12 15:55:01
【问题描述】:

使用img { width: 0; }img { width: 0%; } 样式规则时,具有特定display 类型的容器元素内的图像表现不同

使用 % 以外的任何单位增加width 的值会得到相同的预期结果img 仅占其中显示的部分)。


我尝试更改img所在容器的display类型。结果如下所示。

img 显示的容器display 类型不像预期的那样

  1. -webkit-inline-box
  2. 内联块
  3. 内联-flex
  4. 内嵌网格
  5. 内联表
  6. 表格
  7. 表格单元格
  8. 表格行
  9. 表行组
  10. 表头组
  11. 表格页脚组

不确定它们是如何相互关联的,可能我遗漏了一些东西。


button:first-of-type img {
  width: 0;
}

button:last-of-type img {
  width: 0%;
}
<h3>The image width: 0 (hides it)</h3>

<button>
      <img src="https://picsum.photos/id/1012/200/100">
      <p>Add playlist</p>
</button>


<h3>The image width: 0% (occupies the space (natural img width) and hides it)</h3>

<button>
      <img src="https://picsum.photos/id/1012/200/100">
      <p>Add playlist</p>
</button>

img { width: 0%; } 应该像 img { width: 0; } 一样工作而不占用任何空间,但这里不是这种情况。

【问题讨论】:

  • 我很困惑你想在这里实现什么。如果您不想显示图像,为什么要首先包含它?
  • 我只是好奇它为什么会这样。另外,尝试将0% 更改为,比如说30%。您将看到占用空间保持不变,而图像大小更改为父容器的30%
  • 有什么想法吗,伙计们?
  • 这是个好问题。希望我现在有时间研究它。请注意,差异似乎仅适用于图像元素。如果你在其他元素上尝试width: 0/width: 0%,比如button父元素,渲染是一致的。
  • @Michael_B 不仅是图片,请查看我的答案

标签: html css image display


【解决方案1】:

正如@Talmid 在他的回答中所说,我们面临着一个复杂的计算,使用width:0width:0% 是不一样的。

第一个是绝对值(长度),浏览器无需任何参考即可解析,但第二个是相对于包含块宽度的百分比值,因此浏览器需要知道首先解析包含块的宽度。 (它不会做出0%0 相同的结论)

这个问题会发生在我们有 shrink-to-fit 行为的所有元素(浮动、内联块等)

这里有更多例子:

img {
  width: 30%;
}

span {
  border: 1px solid;
  display: inline-block;
}
<span>
      <img src="https://picsum.photos/id/1012/200/100">
</span>

<span style="float:left;">
      <img src="https://picsum.photos/id/1012/200/100">
</span>

这也可能发生在非图像元素上:

span  {
  display:inline-block;
  border:1px solid red;
}
<div style="float:left;border: 1px solid;">
      <span >some text</span>
</div>
<div style="float:left;border: 1px solid;clear:left;">
      <span style="width:30%;">some text</span>
</div>
<div style="float:left;border: 1px solid;clear:left;">
      <span style="width:0%;">some text</span>
</div>

基本上,浏览器会首先定义包含块的尺寸(在这一步我们不考虑在子元素的width属性上定义的百分比值)。逻辑上,包含块的尺寸将由其内容(收缩以适应行为)定义。之后我们可以根据之前计算的宽度来解析百分比值,因此子元素会缩小。

当然,我们不会再返回计算包含块的宽度,因为我们将有一个非结束循环(一个循环)。

如果子元素使用非百分比值(长度),浏览器在定义包含块的宽度时会首先考虑它,因为它不是相对值而是绝对值:

span  {
  display:inline-block;
  border:1px solid red;
}
<div style="float:left;border: 1px solid;">
      <span >some text</span>
</div>
<div style="float:left;border: 1px solid;clear:left;">
      <span style="width:30px;">some text</span>
</div>
<div style="float:left;border: 1px solid;clear:left;">
      <span style="width:0;">some text</span>
</div>

以下是详细说明此规范的相关部分:https://www.w3.org/TR/css-sizing-3/#percentage-sizing

处理相同的另一个相关问题:How do browsers calculate width when child depends on parent, and parent's depends on child's

【讨论】:

  • 哇!然而,一个非常棒的答案,我需要一些时间才能理解。浏览器试图不创建一个无限循环,从而乍一看向我们展示了意想不到的结果。你能多解释一下“缩小以适应行为”吗?除了floatinline-block 元素还有什么?这意味着所有具有我上面列出的display 类型之一的元素都将具有收缩适应行为?这让我现在很困惑。
  • @Lukas 基本上是收缩以适应元素与全宽元素相反。例如,默认情况下,块元素将占用所有宽度(不关心其内容),但内联块(缩小以适应)元素的宽度将由其内容定义,因此问题是因为内容是相对于他的父母也有一个宽度(一个循环依赖)..是的,你列出的几乎都是收缩适应
  • 现在我明白了:) 谢谢。我会用你的例子和我正在做的项目做实验。如果明天出现任何问题,如果您能帮助我,那就太好了。这么多有价值的信息:)
  • 我认为这是一个很好的解释。但我不确定它是否适用于所有浏览器,因为width: 0 留下了广泛的解释。作为一般规则,最好避免使用无单位的长度值。一些浏览器会自动附加%。其他人px。别人别的东西。没有稳定的保证。此“规则”很少有例外,例如 line-height 属性,它建议使用无单位值。
  • @Michael_B 我会说这取决于属性,但使用 0 不需要单位,我认为它不会被解释为百分比。如果我们参考规范 (w3.org/TR/CSS2/syndata.html#length-units),我们可以看到 0 在长度部分而不是百分比部分中被提及。所以浏览器会将0视为一个长度。省略单位是一种优化,因为它是零。我同意我们应该避免使用无单位的数字(在大多数情况下这是无效的),但使用 0 这不是问题。
【解决方案2】:

容器的宽度由img宽度决定,它是容器宽度的百分比,由img宽度决定,其中...(循环引用)。

当指定 img 的百分比宽度时,浏览器只需将容器宽度设置为图像的预缩放宽度即可解决此问题。

虽然看起来 0% 的特殊情况似乎可以像 0px 一样处理,但也许不是为了与其他指定百分比值的行为一致。

【讨论】:

  • 我喜欢你的想法,但很奇怪我找不到这种行为的官方文档。所以现在就像在猜测一样。