Flexible, fluid, liquid, responsive - layouts which don't rely on a fixed width have had a comeback recently. The CSS max-width property is veryuseful in these designs. So is the knowledge about related browser bugs. Enter IE8.
Images and max-width
When max-width is applied to an <img> tag, the effect should not be restricted to the width of the image. The height has to be adjusted as well, unless there is another rule explicitly setting a value for it.
For instance, a stylesheet might define a width: 100% to make an image fill its container, but limit its size to max-with: 200px. The browser will use both rules to calculate the effective width and, absent any directives for the height, rescale the image: The height is set in proportion to the width. This preserves the aspect ratio of the image and avoids ugly distortions.
This behaviour actually applies to any replaced element that has an intrinsic ratio of width and height. In practice, though, this means images.
What IE8 makes of it
Yet unfortunately IE8 doesn't play by the rules. When both width and max-width are specified and the max-width limit is the lower of the two, the limit should be binding. Indeed, IE8 applies max-width to the width of the image, just as it should.
But the image height remains as if the max-width limit had not come into effect: IE8 calculates the height in proportion to the overridden width rule. The affected images are compressed horizontally (or stretched vertically, depending on how you look at it). This bug is an IE8 peculiarity - it didn't exist in IE7, and has vanished again in IE9.
This is what it looks like:
In standards-compliant browsers
If you'd like to see it on a live page, have a look at the demo. (Of course, you'll only be seeing the distortion if you are viewing the page in IE8.)
How to fix it
There are two ways to deal with this problem, both of them straightforward.
Solution #1: Fix the CSS
The key to making IE8 behave is setting a max-height in proportion to max-width. Suppose an image is 200px wide and 100px tall - and here we are taking about the dimensions of the actual image file, not the display size imposed on it with CSS. Now if max-width limits the image to 50px, max-height should be set to 25px. Done.
The catch is that you have to know the image size in advance. Obviously, this is not an issue with static pages. But if your content is coming out of a CMS, it might be impossible to hard-code these values into the CSS.
Solution #2: Use a script for dynamic pages
Instead of writing fixed max-width values into a CSS file, they can be generated on the fly. This is exactly what the jQuery script below does.
Usage is simple. Put a conditional comment for IE8 in your page source. Within it, load a copy of the jQuery library if it isn't available already, then load the script. That's all there is to it.
This solution may also be useful for static pages. Including the script makes the IE8 bug a non-issue, so it might make sense to use it on every relevant page and just forget about the problem. Again, the script should be wrapped in a conditional comment, as above.
Potential issues, including those caused by IE's caching and by slow connections, should be covered just fine. For more details about how the script works, just have a look at the commented source.
Setting "width: auto" on the img-tag will fix this in a much cleaner way.
"But I want to have my image cover 50% of the container", you might say. Well, there's a simple fix for that kind of scenario. Wrap the image in a div and set the div to to be 50% wide instead. Image will be width: auto and thus seem to have the 50% width.
You are right about width: auto (and that's why the polyfill doesn't kick in if it is set, see the source).
But I don't think adding extra markup to the page, just to fix an isolated browser bug, is in any way cleaner than dropping in a script in a conditional comment targeting IE8 only.
I'd go for an uncluttered document structure for reasons of readability, but also because using a div as a hack is not self-explanatory. You'd need a comment along with each of those divs if other people are working on the site, and perhaps for your future self as well.
Post a comment
Your comment is most welcome - and it will be even more if it is somehow related to the topic ;-) However, we probably all agree that spam and similar nonsense ("cooool thx for sharing!!!!!") shouldn't make it online.