1

Updated shorter question:

Applying max-width on an image inside a table cell:

  • max-width:50PX does one thing, works as expected
  • max-width:100% does another thing, works as expected
  • max-width:max(50PX,30vw) also works as expected
  • BUT, max-width:max(50PX,100%) does totally different and unexpected thing

My guess from the helpful response and links from @temani-afif is that the parent cell sees its child has a max-width:max(%,px) and IGNORES the image entirely when figuring out its own width because of the percentage in the max() function. And in doing so, the image and the table cell separately determine their width leading to overflow.

  • The table cell in this example says, "I am 40px wide."
  • The image says, "max(100%, 50px) = max(40px, 50px) = 50px" → Overflow

I don't think there is way around this under these constraints.


Original question:

I'm the owner of a browser extension that modifies Gmail. Part of that is to put a max-width on messages and inline images.

.email-body {
  width: 800px;
}

.email-body img {
  max-width: 100%;
  height: auto;
  object-fit: scale-down;
}

This works pretty well. It not only prevents massive inline images from being wider than the message, but it also shrinks images in tables so the table does not exceed the max-width on the body of the message.

But this breaks when the table cell is artificially small (HTML emails often have bad HTML). In this case, images are unintentionally shrunk, sometimes made invisible.

Example: 100px IMG in a 40px TD

For instance, the following code will result in the image being shrunk down to 10px wide with the added max-width:100% (which makes sense as 100% = the container's width = 40px):

<table><tr>
  <td style="width:40px;">
    <img style="width:100px; max-width:100%;" />
  </td>
</tr></table>

First attempt: px not % for max-width

Ok, easy to fix. As this is most often a problem for smaller images, if I use a pixel value (50px) for the max-width, it works fine (the image is the full 100px, and the TD grows to match that).

<table><tr>
  <td style="width:40px;">
    <img style="width:100px; max-width:50px;" />
  </td>
</tr></table>

But I don't want to always use a 50px max-width. I want to let a large image span the entire email width while images in tables are still held to the width of their container.

Second attempt: max-width: max(px, %)

I want to use 100% unless it is smaller than some fixed width (say 50px). That should be easy, right? img { max-width: max(50px, 100%); }

<table><tr>
  <td style="width:40px;">
    <img style="width:100px; max-width: max(50px, 100%);" />
  </td>
</tr></table>

Image no longer matches the cell? The 100% inherits from the container (40px). So the max-width is effectively max(50px, 40px) with 50px being the larger number. The image is correctly sized at 50px wide BUT the cell is not expanded beyond 40px this time resulting in overflow and overlap with the content in the next TD.

Any ideas?

You can play with the code here: https://jsfiddle.net/leggett/rqp5uko1/2/

leggett
  • 304
  • 2
  • 6

1 Answers1

0

The explanation about such logic behavior is a bit tricky but to fix it you can consider min-width like below:

tr,td {
  border:1px solid red;
}
Not Good
<table><tr>
  <td style="width:40px;">
    <img src="https://picsum.photos/id/1/200/200" style="width:100px; max-width: max(50px, 100%);" >
  </td>
</tr></table>

Good!
<table><tr>
  <td style="width:40px;">
    <img src="https://picsum.photos/id/1/200/200" style="width:100px; max-width: 100%;min-width: 50px" >
  </td>
</tr></table>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Thanks for taking the time to answer. Given this is applied to all images in any email, I don't want to apply a min-width as there are sometimes images that are much smaller. I would love any pointers to things I can read to understand why the max-width is cascades to the parent cell differently when using a max() than just a straight value. – leggett Dec 13 '22 at 19:32
  • 2
    @leggett it's not the use of max() but the use of percentage which make things a bit tricky. Check these for similar situations: https://stackoverflow.com/a/72712090/8620333 / https://stackoverflow.com/a/67962057/8620333 / https://stackoverflow.com/a/74190703/8620333 – Temani Afif Dec 13 '22 at 20:28
  • Tricky indeed. I think it is partly due to the max() having a percent value in it. –––Another way to ask this: (1) max-width:50PX does one thing, (2) max-width:100% does another thing, (3) and max-width:max(50PX, 100%) does a THIRD thing. ––– My guess from reading those links: The parent cell sees its child has a max-width:max(%,px) and IGNORES the image entirely when figuring out its own width because of the percentage in the max() function. ––– If I use max-width:max(50px,60px) or max-width:100%, it works as expected. – leggett Dec 14 '22 at 22:58