The HTML IMG attributes and styling that I think I want

December 28, 2016

Once upon a long time ago, I put very basic support for inline images into DWikiText (the wikitext dialect used here). At the time I felt I had both simple needs and a simple understanding of the IMG element, so I just specified the image's width and height and called it a day, putting them in as width= and height= attributes in the IMG element.

Much later on, on my personal site, I found that I wanted to include some images and make them as large as would fit in my layout. So I did a hack; I carefully worked out the rough largest image width that would fit in my own browser window in the relatively narrow width I normally keep it at, resized my images to be that wide, and called it a day. This worked for a while (as far as I could see) but then I got an iPhone and looked at my own site with it. The results were not appealing; with my nominally responsive CSS my fixed-width images somehow had tha paradoxical effect of forcing the text content to be narrower (and in a smaller font size) than it could be.

So I did some fiddling to see if I could do better. I decided that I wanted my inlined images to have the following behavior:

  1. never push the natural (text) content width wider (much like how I now want all <pre> content to behave)
  2. shrink down in size instead of getting truncated as the content width shrinks
  3. preserve their aspect ratio as the content width shrinks or grows
  4. don't enlarge themselves beyond their full size, because my inlined images don't necessarily look good zoomed up

Based on both experimentation and reading the MDN page on <img>, what I seem to want is <img> tags that specify a width= value (in pixels) but not a height=, combined with the CSS style of 'max-width=100%'. The CSS max-width gets me my first two things, specifying width appears to mean that browsers won't enlarge the image, and not specifying height appears to make browsers preserve the image aspect ratio if and as they shrink the image. Specifying height as well as width caused at least some browsers to not preserve the aspect ratio, which sort of vaguely makes sense if I squint at it enough.

(You can also put in invalid values for height, like 'x', and get the same effect.)

This feels a bit like a hack, especially the bit about omitting height=, but it also appears to work. Probably there are some less than desirable effects on page layout on slow networks, but I'll live with them unless I can find a better way.

(Some sources suggest that I should set the CSS height to 'auto' as well. The whole area of scaling images to fit in content areas appears to be rather complicated, based on some Internet searches, or perhaps most everyone is over-engineering it with Javascript and lots of CSS and so on. I'm pretty ignorant about the modern state of CSS, so I'm definitely working by superstition.)


Comments on this page:

By Aneurin Price at 2017-01-04 10:57:33:

The only hackiness here is an innate problem with img elements: coming from a time before CSS, they have attributes that confusingly conflict with CSS properties, which are what you should always be using outside of extreme backward compatibility scenarios[0].

In particular, specifying width and not height is not a hack (though you should be using the CSS property, rather than the img attribute); it's the correct way to do what you want.

As a general rule of thumb, images should have a specified height XOR width, except in two scenarios I can think of where it's sensible to use both:

  • You know exactly the dimensions you want in the resulting render, and you want to avoid the page reflowing when the browser fetches the image and finds out its dimensions[1]
  • You want to change the image's aspect ratio

The first reason is fairly common, but it doesn't apply to you because you're using max-width and therefore don't know exactly the dimensions you want in the resulting render. I think you could probably do something with CSS calc() to work out the correct height to avoid reflows here, but I've never tried. (I might investigate this actually, because constant reflows are the main reason I hate using the web on my phone and I'd like to get some sense of superiority that if only I had designed this site, it wouldn't have that problem :D)

There is sort of a third, in that it can sometimes be necessary to set the other dimension (height in your case) to 'auto', which is its default value, if the element has ended up inheriting some other CSS rule which sets it to something undesirable - this is why you've seen suggestions to set "height:auto".

[0] I can give some reasons for this if anybody cares.

[1] NB: If you Google for reasons to use img attributes vs CSS properties, you will find a lot of people - including a number of highly voted Stack Exchange answers - giving this as a reason to use attributes. These people are confused: this is not a reason to use one over the other, as CSS properties give the same benefit.

Written on 28 December 2016.
« A perhaps surprising consequence of Requires dependencies in systemd
One reason why Go's increment and decrement statements are good to have »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Wed Dec 28 01:46:31 2016
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.