Using CSS to control image variants
Posted on:One of the challenges faced when working with responsive images has been managing each of the image variants, and deciding which image file to request depending pixel ratio and network connection.
To generalize an example, a paragraph element containing text provides the structure, and its presentation comes from CSS. If the paragraph renders to 3 lines of text, and the browser changes size to where the paragraph now renders to 5 lines of text, the content is still the same, but only its presentation has changed.
I think content images should be seen in a similar manner. The img element provides the structure and the src attribute is the content. However, depending on browser conditions, the presentation of the image should change, not the content. Whether an image of your cat is viewed on a high-res or low-res display, the image is still the same “content” of a cat; its just that they’re different variants of the same image.
The img element, or whatever next-gen element comes around for displaying images, should only worry about providing the content of the image, and let the CSS control presentation, just like any other element. And because image filename examples, such as milo.jpg and milo_2x.jpg, are actually providing the same content, just a variant in quality, the CSS should be given the task of deciding which image variant to show.
Much of this has been discussed and this post offers some great ideas, specifically the image-set() CSS: http://lists.w3.org/Archives/Public/www-style/2012Feb/1103.html
Image-set() CSS is a great format for the browser to decide which image variant to show depending on browser conditions. For example, if the browser has a device pixel ratio of 2 and high-bandwidth, then the browser would know to show image file X, otherwise show image file Y. I also agree that using image-set() should be preferred over media queries, because (as the article referenced above mentions), “Using @media pushes the two asset references apart from one another, whereas such a function keeps related asset references together. It also helps keep selectors DRY.”
However, the direct image references may still cross the line by putting specific content image filenames in the CSS (yes background-image url() has specific image filenames, but I see background images as presentation, not content). Instead of having CSS specify exactly which image file to show, the CSS should be used to specify which image variant to show.
I put together foresight.js more as a proof-of-concept than anything else. It’s a tool to make responsive content images work in today’s browsers, and judges which image variant to show depending on network connection speed and device pixel ratio. This project is not attempting to be an end-all answer for responsive content images, but rather a practical workaround for today’s browsers.
The original version of foresight.js used a lot of element attributes and javascript configurations, which was in violation of my points above. But since the web community has showed an interest in foresight.js, I decided to take it another step further and made it configurable using CSS.
Foresight.js uses a number of tricks to pull off responsive images, none of which are groundbreaking, but rather very common workarounds. However, the CSS is applied to the responsive content images and follows the concepts that I described above. The javascript of foresight.js is doing the work I believe the browser should do, which is to decide which image variant to show depending on browser conditions. But the javascript itself is not what I would like to present, but rather how CSS could be used to control image variants of the same image, without hardcoding image filenames.
Again, foresight.js is a proof-of-concept for using image-set() CSS, along with formatting image requests using URI templates and URI find/replace methods. Hopefully this can help spark further discussions to eventually shed some light for handling responsive content images:
https://github.com/adamdbradley/foresight.js
I like this approach, I think you make a good arguement about the distinction between content and presentation for handling image variants.
I particularly like the image-set approach, especially since having the CSS handle which image to serve means the markup is fully backwards compatible and I think that’s of real value.
Good work, I’ll have a look over the js when I have some time, but it looks promising.
I like the image-set approach as well. It solves the issues of trying to keep our logic DRY. I’ve briefly looked through foresight.js a couple of times and it’s very clever Adam. The whole font-family image-set trickery was an interesting concept. I also like the URI templates and the URI Find/Replace. I’m looking forward to taking a closer look at this and experimenting with it more.
-webkit-image-set should update dynamically when the device scale factor
changes: http://trac.webkit.org/changeset/113490
Pingback: Move on! | Responsive Images Community Group
Very good solution, but this won’t work without JAvaScrip, what about using only CSS like here: how to resize images proportionally using CSS for responsive web design. This uses only CSS, even not the new one like CSS3. So, it will work in IE9 and IE8.