Setting the image `width: 0` hides it, while `width: 0%` makes it occupy the space, too

As @Talmid said in his answer we are facing a complex calculation. Using width:0 and width:0% aren’t the same.

The first one is an absolute value (a length) that the browser can resolve without the need of any reference but the second one is a percentage value that is relative to the width of the containing block so the browser need to know the width of the containing block first to resolve it. (it will not do the effort to conclude that 0% will be the same as 0)

This issue will happen with all the elements where we have a shrink-to-fit behavior (float, inline-block, etc)

Here is more examples:

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>

This can also happen with non-image elements:

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>

Basically, the browser will first define the dimension of the containing block (at this step we don’t consider the percentage value defined on the width property of the child element). Logically the dimension of the containing block will be defined by its content (the shrink-to-fit behavior). After that we are able to resolve the percentage value based of the width calculated previously thus the child element will shrink.

Of course we will not get back to calculate the width of the containing block again as we will have a non-ending loop (a cycle).

In case the child element uses a non-percentage value (a length), the browser will consider it first when defining the width of the containing block since it’s not a relative value but an absolute one:

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>

Here is the relevant part of the specification detailing this: https://www.w3.org/TR/css-sizing-3/#percentage-sizing

Another related question dealing with the same: How do browsers calculate width when child depends on parent, and parent’s depends on child’s

Leave a Comment