Media Queries Can't Be Used for Resolution Negotiation

Last updated:

Or, why any Responsive Images solution based solely on MQs is doomed to failure.

tl;dr

Good, user-friendly behavior for deciding which resolution to send depends on several factors, which are difficult to get right. One of the major considerations, bandwidth, is variable, which means you can flip from "high" to "low" within a page load, You don't want to throw away the "high" images and request the "low" ones in this case (as that's ridiculous and user-hostile) but that's precisely what using Media Queries would require.

Let's Get Things Clear

One of the major use-cases for Responsive Image (though, unfortunately, not really one addressed by the Responsive Images CG) is the ability to send high-res images to high-DPI screens like the iPhone "retina" screen, while still sending normal images to everyone else.

Unfortunately, "has a high-DPI screen" isn't the only thing you want to be concerned about. High-DPI images are much larger than normal images (generally, one with double DPI will be four times the size), so you'd also like to segregate this by bandwidth somehow, so phones on shitty connections get the normal image quickly, instead of the high-res image slowly.

You may even want to go further, so that initial page-loads on mobile devices that are initially pretty zoomed out get an even lower resolution, lower than normal, just to make it happen even faster.

Already, we're looking at enough factors that it seems difficult to fit Media Queries to the solution. A good interaction with the user requires some pretty subtle reasoning and careful set-up of the queries. (Not to mention, it depends on several types of queries that don't currently exist.)

A Bandwidth Media Query

Now, let's just look at the hypothetical bandwidth query itself. Unfortunately, the concept is probably fatally flawed.

For one, bandwidth is complicated. It's not just a bit rate - latency is very important. Most of the time, phones can get a pretty good download rate, but their latency is terrible, so your goal above all else should be to minimize network requests, and not care as much about filesize.

That ties into the next point - bandwidth is variable. On a desktop, you might get "burst" speeds at the beginning of a page load, then significantly more restricted bandwidth after a second or so. A phone can start loading a page on a speedy 4G connection, but then get carried into an elevator that drops them into Edge mode.

If the bandwidth available changes, a hypothetical bandwidth query will change as well. You'll flip from "high" to "low", and thus flip from saying "use this high-res image" to "use this low-res image".

Whoops! This literally means "throw away that high-res image you've already downloaded, and pull down this low-res image instead". That's exactly what you don't want; the user is in a low-bandwidth situation, so you don't want to force them to make more requests for resources they already have better versions of. Unfortunately, Media Queries are stateless, so you can't say "request the low-res image, unless you've already finished getting the high-res version". Even if you could hack in a patch for this one case, what do you do about all the other properties that might be applied by the MQ?

More importantly, what about when you switch from "low" to "high"? Should you keep the current low-res image, or should you go ahead and request the good ones? Unlike the other case, both options are potentially reasonable. Which one is correct for the situation might be based on a prediction of whether you'll stay in high-bandwidth mode, or other subtle factors that are even more difficult to express in MQs.

In Other Words

You simply can't make a good decision about which resolution to send to the user based on information from Media Queries. It's fundamentally a hard decision based on information that's difficult to expose in a reasonable manner.

As such, any Responsive Image solutions that concentrate on using MQs to decide between images can not solve this use-case. This is a pretty important one, so you can't just ignore it.

It seems that the best way to solve this is to just announce to the browser what the resolutions of your URLs are, and let the browser decide which one to request based on its own heuristics. This pushes all the difficulty into a single, centralized place with access to all the necessary information, and lets browsers make the decision they think best across all pages.

(a limited set of Markdown is supported)

... or you use alternative techniques like vector graphics or small custom fonts unless you need to display photos - in that case you are doomed (for now) ...

Reply?

(a limited set of Markdown is supported)