The logic behind displaying an image responsively is complicated. It involves determining how large the image will be displayed, as well as understanding whether the user is on a high-resolution display, among other things. Thankfully, the browser is better equipped than we are to handle this logic. All we need to do is give it some hints. We’ll use the srcset attribute to provide a list of image assets to choose from, and the sizes attribute to tell the browser how large the image will display at various breakpoints.
Yes, the syntax is still the same as in 2014, but it’s good to be remembered of it … I always find myself looking things up again when it comes to Responsive Images 😬
Besides using an SVG as a background image in CSS, you can serve SVG foreground images in HTML using one of several embedding techniques, each of which has its advantages and use cases. Unless you’re in need of interactivity or external styling, <img> is the standard way for loading an SVG image, but it has one disadvantage: you currently need JavaScript to provide fallback and/or change the image source for art direction. In this post, I’ll talk about a better way to do that, using the <picture> element.
<picture>
<source srcset="examples/images/extralarge.jpg" media="(min-width: 1000px)">
<source srcset="examples/images/large.jpg" media="(min-width: 800px)">
<source srcset="examples/images/medium.jpg">
<img srcset="examples/images/medium.jpg" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
</picture>
The picture element and associated features are W3C standard HTML features that allow web developers to deliver an appropriate image to every user depending on a variety of conditions like screen size, viewport size, screen resolution, and more. Picturefill is a polyfill that enables support for the picture element and associated features in browsers that do not yet support them, so you can start using them today!
A consensus was reached on the spec. Chrome, Firefox, and Opera are implementing it as we speak. Until then (and for other browsers) use this one.
When working with images on small screen devices it is recommended to focus on the subject: don’t just show a scaled down version of the photo, it’s better to remove some of the background scenery and show the person on the photo (see the Obama example at the top of this post on responsive images).
Enter Focal Point:
A small set of CSS classnames to help keep images cropped on the focal point for responsive designs. Using only HTML/CSS, web authors can specify an image’s focal point, which stays as the image’s primary focus, while the image’s available width changes on responsive webpages. Crop and re-size images depending on available width and let CSS to do all of the work, and without any JavaScript
Now that phones, tablets and laptops use high-resolution, “can’t tell it’s pixels” displays it’s time to take the plunge and make your sites and apps ready for retina.
With my ebook you’ll be up to speed in no time, with easy to follow step-by-step instructions on creating stunningly beautiful high-resolution websites, that load fast and work in any browser
Responsive images is a surprisingly complicated topic, and one that’s been steadily gaining attention over the last year as more developers discover they need them and then discover there’s no good solution yet. This article aims to give an overview of the problem itself, and show the different proposals in the works to address it.
Pngy is a bit of jQuery that allows you to load images of different file sizes based on a page’s load speed. So, if the load speed is slow, Pngy can load your small image. If it’s fast, it can load a hi-res image. It’s kinda like a ping test in Javascript.
Anystretch is a jQuery plugin that allows you to add a dynamically-resized background image to any page or block level element. The image will stretch to fit the page/element, and will automatically resize as the window size changes.
Handy when having a fluid layout/responsive design.
UPDATE: Reader Oemebamo pointed out that this can be achieved with CSS, using background-size: cover;. Turns out background-size is widely supported (thought it was Chrome only).
The past few weeks a lot has been going on around one of the challenges of responsive web design, namely responsive images. The gist of it is pretty straightforward: it’s not a good idea to let a device download a big image if that device is a small-screen device. It’s better to serve that device an image that (approximately) fits its screen.
A current proposal that is getting quite the attention is to introduce a <picture> element with some various <source> children, this inspired upon how <video> and <audio> are coded. Key difference though is that you explicitly define the minimum (or maximum) required width along with it.
<picture alt="Alt tag should accurately describe the image represented by all sources, though cropping and zooming may differ.">
<source src="mobile.jpg" /> <!-- Matches by default. -->
<source src="high-res.jpg" media="min-width: 800px" /> <!-- Overrides the previous source over 800px before any assets are fetched, resulting in a single request. -->
<img src="mobile.jpg" /> <!-- Fallback content, in the event the <picture> tag is completely unsupported by the user's browser. -->
</picture>
An other proposal that I quite dig is a new image format that acts as a container and can hold several images inside it. Think of it as a .zip with some images inside it (or if you’re familiarized with OS X: a .icns file). The implementation could be done in such a manner that the browser only downloads the wanted size based upon it’s screen size.
One that caught my eye though — because of its pure simplicity — is Responsive Enhance: Serve the browser a low-res image. If more screen estate is available, let it pull in a high(er) resolution image.
Suppose the small image is 20K and the large image is 60K. That means that desktop browsers are now loading 80K of images (instead of 60). On the face of it, this sounds like really bad news for performance… but because that extra 60K is being downloaded after the page has downloaded, the perceived performance isn’t bad at all. In fact, the experience feels quite snappy.
Agreed, it’s not good to download something twice, yet the advantages (perceived speed) currently outweigh the disadvantages (downloading an image twice + the fact that this won’t work if JS is disabled).
The Elephant
When talking about responsive web design and mobile devices, one of the key aspects that was always pushed forward was context, which has become something vague to define: it’s not because a user is visiting your site via a mobile device that he/she is “on the road”. In the same line, one can also state that:
And this is the elephant. All the suggested solutions I’ve seen so far only take the screen estate into account, neglecting the connection speed the device has.
To me, a proper solution would also take the connection speed into account: if a device has the space to show a bigger image, and the connection can handle it: enhance.
A Possible Solution
As there’s already a navigator.onLine property available (demo) I think it’d be fairly easy to extend navigator with a speed property. That property in its turn could then easily be mapped/expanded to become available from within media queries, or even an HTML attribute.
The suggested <picture> solution could evolve into something like this:
<picture alt="Alt tag should accurately describe the image represented by all sources, though cropping and zooming may differ.">
<source src="mobile.jpg" /> <!-- Matches by default. -->
<source src="high-res.jpg" media="(min-width: 800px) and (min-speed: 3G)" /> <!-- Overrides the previous source over 800px before any assets are fetched, if the the user has at least a 3G connection. -->
<img src="mobile.jpg" /> <!-- Fallback content, in the event the <picture> tag is completely unsupported by the user's browser. -->
</picture>
The proposed 3G value for min-speed in the example will need some tweaking though. If one would have a speed with the value wifi, that could actually mean nothing: he could easily be connected via WiFi to his iPhone which is on 3G. Better solutions could be values in the likes of slow – good – fast or actual rates 100kbps – 10Mbps – ....
Does this extension look something to you? Or have we have no need to detect the connection speed of device? It’s clear that I myself think we do need it … so let’s start a discussion 😉
UPDATE #1: As Jan posted below it’s better to let the browsers handle downloading the best size, instead of putting the responsibility in the developer’s hands. If you combine this idea along with the container format (cfr. the .icns file) then there’d be no actual need for the <picture>element: just define an img set the src to the container image and the browser will cherry-pick the appropriate size based on the screen estate and the connection speed. The rules to decide which on the browser need to fetch will be tricky to define though (there will be some edge cases), but that’s a nut we can definitely crack.
UPDATE #2: Lennart Schoors (from briccs.net) hinted on Twitter that the connection speed is in some (draft of a) W3 spec. Mathias Bynens eventually pointed towards that spec, namely The Network Information API which has a Connection interface which holds a bandwidth property. As this can eventually become available, the inclusion in a media query or attribute isn’t that far away.