There is a real need for serving media that is appropriate for the device and circumstance, since we know so little about any particular web request. I recently posted a blog post with so many images on it the page weighed in at 2.29 MB. I should have posted a warning when I tweeted it: "Don't click this if on a 3G network, it probably take forever, just check it out when you get home."
Ideally, all those images I served up could have had a lower-res version of themselves that display on browsers with smaller browser window sizes and/or slower connection speeds. Even in cutting edge browsers, there is no native way to do this yet. So it's a good time to start talking about how we want that to work as web builders. Perhaps we can influence how the spec shapes up.
Let's limit this conversation to inline raster images. As in, the things today served as
<img>. As I see it there are three paths we can go.
- Create new element that exists just to serve this problem.
- Create a new image format designed to solve this problem.
- Do nothing, fix our problems with other technologies.
Each of them has advantages and disadvantages. Let's look at each.
Create New Element
<picture alt="description of image"> <!-- low-res, default --> <source src="small.jpg"> <!-- med-res --> <source src="medium.jpg" media="(min-width: 400px)"> <!-- high-res --> <source src="large.jpg" media="(min-width: 800px)"> <!-- Fallback content --> <img src="small.jpg" alt="description of image"> </picture>
- Mimics other media syntax like
<audio>, which makes sense.
- The fallback makes it backwards-compatible with browsers that don't support it, which is extremely important. We can't have images that just don't work in older browsers.
- Gives us web authors the control to show exactly what we want under situations we specify.
- It's a whole lot more complicated than
<img>. Harder to teach, harder to learn, more code to write. Easy to screw up.
- Muddies the water of CSS and HTML a bit, by bringing the media query syntax into HTML.
- Similar issues to why inline styles are bad. Makes future updates more difficult. Not a reusable abstraction.
New Image Format
The impetus behind this blog post came from conversations I with Christopher Schmitt and a blog post he wrote. Christopher is of the opinion that a new image format is the ideal solution.
This new image format would essentially have multiple versions of itself inside of it.
Which image is delivered by a program like a web browser is a determination that can be made by a virtual handshake between the browser and the web server.
So perhaps the file is 800k all together, but within it is four different versions of itself: 500k, 200k, 50k, 10k. Through some kind of standardized set of rules, one of those four images would come across and be displayed by the browser.
Seem like a fantasy? There is already an image format like this called FlashPix, which handles even more drastic versioning. Think new image formats are impossible to implement? WebP is gaining support at a decent pace.
Ultimately the syntax would remain just as it is now:
<img src="unicorn.rpng" alt="fancy unicorn">
I just made up that file extension, but "responsive PNG" would be fine with me.
Christopher likes this approach because
it allows the continued use of the IMG element which is ingrained into the bones, the very marrow, of the Web.
I like that thinking. No need to turn our backs on an element which has worked so well for so long. But of course we wouldn't. There is no need to replace
<img>, only build upon it and offer alternatives.
- Keeps the syntax simple. Works the same way it always has.
- Keeps authoring simple as well. One file, not multiple. Adoption would probably be quicker and more people would actually do it (less people would make 4 versions of every image and hand craft queries to serve them).
- Possible loss of control. In order to keep things simple, the image format would do the logic of what exactly gets served. Will it always make the right call? What does it factor in? Parent container width? Network connection speed? Pixel density? A combo?
- Not backwards-compatible. What happens in browsers that don't support the new format?
<img> and hot-swap the
src with the new format for a while until the new format has ubiquitous support. A little heavy-handed perhaps, but workable.
Adaptive Images by Matt Wilcox is a ridiculously clever solution that using a tiny sprinkle of JS just to measure the current screen size and set a cookie, and then all requests for images are routed through some PHP which determines which version of an image to server, appropriate to screen size.
<img src='//src.sencha.io/http://mywebsite.com/images/unicorn-hires.jpg' alt="unicorn" />
That's the simplest possible usage, it can get a lot fancier than that. It's a third-party Beta service though, so be aware of the inherit concerns of that (e.g. they go down, your images don't load). I imagine it will ultimately be a paid service.
- We don't rock the boat of standards.
- No waiting for browsers to catch up on supporting anything new.
- Is this just ignoring the problem? Aren't standards supposed to help with real problems?
- The code needed to do this right is heavy-handed.
Where I Land
Relying on older technology and hacks isn't enough for me, but I can't decide whether I prefer a new format or new syntax. Maybe both? Maybe a hybrid? I feel like the syntax is more likely because there is more discussion about that. A format is a much taller order and I've heard no whispers of active development on anything like that.
It'll be a fun day when I can update this blog post with "official" best practices!
- Brad Frost: Optimizing web experiences for high resolution screens
- W3C: Responsive Images Community Group
- Tim Kadlec: Media Query & Asset Downloading Tests