Flexible, fluid, liquid, responsive - layouts which don't rely on a fixed width have had a comeback recently. The CSS max-width
property is very useful in these designs. So is the knowledge about related browser bugs. Enter IE8.
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.
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:
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.)
There are two ways to deal with this problem, both of them straightforward.
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.
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.
<!--[if IE 8]>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"
type="text/javascript"></script>
<script src="[YOUR PATH HERE]/ie8_fix_maxwidth.js"
type="text/javascript"></script>
<![endif]-->
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.
Thanks! Hopefully that wretched browser will dIE soon!
We'll have to deal with it for another couple of years, I'm afraid, but I share your sentiment ;)
ohhh I`ve wasted so much time with this bullshit. Now It works....Thanks! Solution #1 solved my problem.
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.
Still happens in IE11
Actually no, the max-width bug is not an issue in IE11. Use IE11 to have a look at the page demonstrating the bug:
https://www.zeilenwechsel.de/it/samples/ie8-max-width-bug/buggy.html
As you can see, all elements are displayed as they should.
But to me one extra line at the very beginning of the stylesheet seems cleaner than six lines of HTML on every page of the site.
No, not really, and honestly I don't think this is a matter of taste or coding style, but rather one of maintainability.
A percentage width of 100% could be handled by
width: auto
, unless an image needs to scale up beyond its native size - so that part would basically work. Other percentage widths would require additional markup, though, as an IE8-specific hack (see the comment above by commenter #3, and my reply). Browser bugs really shouldn't be fixed by sprinkling random bits of HTML across a site. Those fixes are very likely to break when the HTML is refactored.A JS-based, targeted bugfix, when added to the base page template, requires zero administrative effort, restricts the performance penalty (additional request) to IE8, and allows you and anyone else on the team to forget about the issue entirely.
Unless you are dead sure you won't need any other image scaling than
width: auto
anyway, a blanket fix is better than individual repairs. If you ask me. Which you haven't ;)Don't really get what you're saying. Just set everything to width auto on the first line of the stylesheet, and then, as far as I understand, IE8 behaves (in his respect, anyway) the same as other browsers. No IE hacks or extra bits of HTML are required. (And this in itself is not an hack, but perfectly regular, valid CSS, setting the property to the value it has by default in other browsers.)
If, for example, an image needed to expand to fill a sidebar then, e.g.:
will be the CSS you need for all browsers (nothing different or extra for IE8) and will simply override the
width: auto
already set.If you disagree, provide me with a specific example where this approach will fail or cause some difficulty.
Oh, that would be a different story altogether. I got you wrong, perhaps because I'd never heard of that hack. In fact, that would be the most elegant solution to the problem.
I have tried your suggestion now, though, and it doesn't have any effect. Here's a quick demo for it. Matters don't improve if the line is added at the top of the default style sheet, either. So, no luck.
(If you think I got the setup wrong, perhaps you can post a link to a working example.)
Firstly, thank you for engaging in this discussion with me.
Secondly, you've been quite right all along!
The real-life situation in which I came across this issue was in a WordPress theme.
What I wanted was for images to stay within their containing element (typically
div
) and so I was settingmax-width: 100%
, which, where its effect was to shrink images, was resulting in the width being reduced as needed but the height remaining the same.In WordPress, when an image is added to a page or post the height and width attributes are automatically set within the actual HTML (as actual HTML attributes, not as part of a style attribute). Although I had NOT specified a CSS width for the image, it seems that IE8 was using the HTML width attribute (larger than the
maxwidth
) to calculate the height, resulting in the image being stretched heightwise.My adding
* {width: auto}
to the stylesheet was overriding the HTML width attribute and allowing the image to scale proportionally. (img {height: auto}
was already elsewhere in the stylesheet, else the HTML height would have prevailed.)In summary, the issue I was experiencing was slightly different from that described on this page and was NOT caused by a CCS width being used to calculate the height, but rather the HTML width attribute. Setting CSS width to
auto
overrode the HTML width and allowed the image, in the absence of any other CSS width, to scale correctly.If I had been using a CSS width to size the image then you are quite correct that a script solution, such as yours, would have been needed.
(Finally, to echo the first comment on this page, let's hope than now MS is no longer supporting XP, in the not too distant future we can all stop having to make allowances—and special style sheets—for this wretched browser.)
That is a different issue indeed. Thank you, though, for having a go at the max-width problem. Time will eventually solve it for us ;)
What if the image is larger than what you want displayed, and at the same time you also want to use "max-width"?
e.g.,
{img src="globe.jpg" width="200" height="100"}
But the actual globe.jpg is 5000x2500px and you want to use:
img {max-width:100%}
Now if you used:
img {width:auto; max-width:100%}
Then the image width will jump to 5000px instead of staying at 200.
What you describe is actually the correct way to go about it, and it does indeed work. In your example, you have set
width
andheight
attribute on the image tagwidth: auto
style which overrules those attributesmax-width: 100%
cap on the image width, limiting it to the width of the containing element.So if you stick the
img
into adiv
which is 50px wide, the image will be limited to that 50px width.My guess is that in your case, the containing element is not limited in its width and is allowed to expand as much as it needs. The
max-width
cap doesn't apply then, and you are left withwidth: auto
, which will make the image 5000px wide.Am I right?
How is the actual way to have the script working in IE7 and IE6? You mentioned it could be possible at a computational cost. my plan is to use condition, so i do not have to worry about any extra doings like extra calculations in IE9. thanks so far!!
Not sure what you are referring to ... The script solves a problem in IE8, and IE8 only. There is no need to target IE6 or 7 (apart from the fact that these versions should not be on any developer's plate in 2016).
Comments are disabled.
Comments have primarily been disabled because of a flood of comment spam. Turning them off has also been an easy way to comply with EU privacy and data protection regulations. User nicknames have been replaced by anonymous placeholders. All data relating to the original commenters has been deleted.