December 26, 2018

About Images

General rules:

  • Use JPGs for photos and PNGs for graphics or other images that require transparency
  • Use smaller PNG-8 instead of PNG-24 for graphics with a limited number of colors. To decrease the size even further, you can also reduce the number of colors, from 256 to 16
  • Use SVGs (vector graphic images) for icons and logos. They will scale nicely without increasing the size of your file
  • Use inline images below 10KB as 64base encoded strings (sparingly)
  • The actual width of an image shouldn’t exceed the width of the largest container it will be displayed in, multiplied by two (for retina displays)

Apps for optimizing images:

  1. Squoosh
  2. SVGO
  3. ImageOptim
  4. SVGOMG

Responsive images in HTML

You can decide which image to serve depending on the screen’s pixel density with the srcset attribute:

<img srcset="image_1x.jpg 1x, image_2x.jpg 2x" src="image_1x.jpg">

Depending on the actual display density, the browser will choose the right one. The srcattribute points to the fallback option.

Picture element

Meet the HTML5 picture element. It accepts the source and img elements as its children. We can use the source element to list additional image formats that we want to serve to the browser.

The source element opens up a whole new world of possibilities. It accepts media queries!

First, in the media attribute, we use the media query and then, in the srcsetattribute, we place the appropriate image. And we can use as many sourceelements as we wish.

The last secret of the srcset attribute is that it also accepts pixel densities. We can decide which image we want to serve on which screen and at which pixel density. The trick is to list image files in the scrset followed by a space and the pixel density factor, for example: 1x2x3x, or even 4x.

<picture>
   <source
   media=”(min-width: 900px)”
   srcset=“image-lg_1x.webp 1x, image-lg_2x.webp 2x”
   type=“image/webp” >
   <source
   media=”(min-width: 601px)”
   srcset=“image-md_1x.webp 1x, image-md_2x.webp 2x”
   type=“image/webp” >
   <source
   media=”(max-width: 600px)”
   srcset=“image-sm_1x.webp 1x, image-sm_1x.webp 1x”
   type=“image/webp” >
   <img
   src=“image-lg_1x.jpg”
   type=“image/jpeg”
   alt=”image description”>
</picture>

Important: Notice that in the img element the srcset attribute should be placed before the src attribute. Otherwise, the browser will download the src image first and then, if it finds a better image in the srcset, it will download this one as well. This way we would end up with two images.

Responsive images in CSS

Solution from the future

The <img> tag also has one wonderful property - object-fit. By the way, it works for video containers.

.myImg {
 object-fit: cover;
 width: 320px;
 height: 180px;
}

That's all! The object-fit controls the placement of the element if the width and height are different from its actual size. Instead of cover, you can use the contain value.

Netflix Solution

This trick works everywhere and only requires to wrap the image in an additional container. The proportions are saved with the help of paddings, given in percentage, and the picture is absolutely positioned.

.wrapper {
 position: relative;
 padding-top: 56.25%; /* 16:9 Aspect Ratio */
}
img {
 position: absolute;
 left: 0;
 top: 0;
 width: 100%;
 height: auto;
}

A simple solution

img {
 height: auto;
 width: 100%;
 /* more control with max-width */
 max-width: 720px;
}