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/