Table of Contents
Responsive images is one of the pillars of responsive web design philosophy. For a long time web designers have to use various creative ways to solve the problem of serving different devices with different image files. However, this should not be necessary now thanks to new picture element which was released by W3C. Before you jump right in and start using the picture, you have to know that it is not supported yet by almost any browser. Chrome support start with version 38 (in 37 you have to enable it in flags), Firefox with version 33 and Opera with version 25. In this post, I will show you some of those more or less tricky ways and in the end will be example for using the newest picture element.
Single image
First thing you can do to “solve” the issue of responsive images is to use one image declared for example in <img> element and add CSS styles.
HTML:
<div class="image-container"> <img src="http://i.imgur.com/BlihuYt.jpg" alt="Elephant in the room"> </div>
CSS setting will require to set “width” and “height” for “image-container” div and also “with” rule for img element. For this example, let’s set the width of div to 30% and height to 50%. Width of the <img> element will be 100% so it will stretch itself automatically as the parent div will change.
CSS:
.image-container { width: 30%; height: 50%; } img { width: 100%; }
Another trick is to define source of image file in CSS “background” property with “no-repeat” value after it and also using “background-size” property with value of “cover”. This will trick have some negative side-effects. The most visible will probably be when screen resolution will have different ratio than used image. In that situation, image will break its width and height ratio to fit the resolution. The result image can be distorted or blurred. This is caused by “cover” value in “background-size”. This value force image to adjust itself to fit the parent width and height no matter what it will take.
HTML:
<div class="image-container"> <img src="" alt="Elephant in the room"> </div>
CSS:
.image-container { width: 30%; height: 50%; } img { width: 100%; background: url(img/elephant.jpg) no-repeat; background-size: cover; }
Multiple images
Previous examples resulted almost all the time in “damaged” pictures in some way. Pictures got often distorted, blurred, pixelized or whatever. More suitable and less painful solution is to define sources of images files in CSS, but inside media queries. This way, browser will load different images according to resolution and your media queries. For this example we created three versions of our image – mobile, tablet and desktop version. Next step is to use media query for every image. For media queries let’s use most typical breakpoints – 320px, 768px, 769px and bigger.
HTML:
<div class="image-container"> <img src="" alt="Elephant in the room"> </div>
CSS:
@media screen and (max-width: 320px) { img { width: 100%; background: url(img/elephant-mobile.jpg) no-repeat; background-size: cover; } } @media screen and (max-width: 768px) { img { width: 100%; background: url(img/elephant-tablet.jpg) no-repeat; background-size: cover; } } @media screen and (min-width: 769px) { img { width: 100%; background: url(img/elephant-desktop.jpg) no-repeat; background-size: cover; } }
– note: it is better to define your breakpoints for media queries in em units.
In this situation you can overcome many side-effects that appeared in previous trials. It also requires you to create multiple version of image.
Picture element
Now comes the revolution. Newest picture is something like <img> element mixed with media queries. If you like comics and mutants, you may like it too. Steps are following … Create new <picture> element in your html file and inside it nest couple of <source> elements (amount depends on how many images will you use). <source> element has two attributes – media (like media query) and src. In media you just define min/max-width or min/max-height with breakpoints. The last source element, with default picture, does not require media query. One last thing … you can also add classic <img> element as fallback for non-supporting browsers. You can also add a paragraph of text to display message in non-supporting browsers.
HTML:
<picture> <source media="(min-width: 679px)" src="elephant-desktop.jpg"> <source media="(max-width: 678px)" src="elephant-tablet.jpg"> <source src="elephant-mobile.jpg"> <img src="elephant-fallback.jpg" alt="This picture loads on non-supporting browsers."> </picture>
Summary
There are couple tricks you can use to deal with responsive images. It can be either using one image for everyone and risk side-effects like distortion or serve multiple versions for various resolution and devices. It depends on you.
If you liked this article, please subscribe so you don't miss any future post.
If you'd like to support me and this blog, you can become a patron, or you can buy me a coffee 🙂
Reblogged this on Amir Naeem.
Just a question. Why is it better to define the breakpoints for media quries in em units?
Great question, thanks for asking. The reasons is that layout can then adjust to the change in font-size. This further ties our breakpoints to our content. If you use pixels, when you zoom-in, nothing will happen. Media query will not triggered. In case of em’s, media query will be triggered and so the layout will be changed. it is also more future-proof because ems are fluid and, after setting font-size on html or body element. stay same no matter what size is set on user’s device.