📝 CSS-Tricks 257: The One About Images

View this newsletter on the web.

[Robin]: When it comes to web development I feel like images have been in a state of constant flux over the past few years. What’s the best way to add an image to a website? Well, that question is much more complex than it looks at first and, depending on the month, it seems like there’s new advice from every direction. This is partly a good thing because there’s been an awful lot of improvements made in this space.

For example, did you know about the image-set() CSS function? Me neither! According to this great post by Ollie Williams, it’s been supported in Chromium since 2012(!) and it just landed in Firefox 88. It allows us to load different images in CSS depending on screen resolution:

.element { background-image: image-set("platypus.png" 1x, "platypus-2x.png" 2x); }

This might look familiar to you if you’ve ever used the HTML srcset attribute that looks something like this:

<img alt="A baby smiling with a yellow headband." src="baby-lowres.jpg" srcset="baby-highres.jpg 2x" >

The browser will look at that 2x part and if it’s a higher pixel density display it will load that one instead of the low-res image. But let’s say you wanted to use a next-gen image format that isn’t supported in a lot of browsers right now, such as AVIF. You could then write something like this first:

.element { background-image: url('kitten.png'); }

This is the fallback image you want to use for browsers that don’t support image-set but then you can add to that code like this…

.element { background-image: url('kitten.png'); background-image: image-set( "kitten.avif" type("image/avif"), "kitten.jpg" type("image/jpeg") ); }

image-set lets you add a series of images that you want to load depending on the device. The first image here is the next-gen image format but if a browser doesn’t recognize it, then cool — it’ll ignore it and use the jpeg. Just like srcset allows you to do as well.

This is pretty dang amazing, especially as there are new image formats looming on the horizon like AVIF (which is a format already supported in Chrome and Android browsers).

Speaking of serving sharp images, Jake Archibald just wrote all about that. He writes about how to cater for low-res and high-res screens in a lazy way and also the most intense way imaginable by using the <picture> element. Here’s what Jake calls the lazy way:

Here’s the technique I use for most images on this blog: I take the maximum size the image can be displayed in CSS pixels, and I multiply that by two, and I encode it at a lower quality, as it’ll always be displayed at a 2x density or greater. Yep. That’s it.

That’s been my approach with most projects, too. But also dang is it great to know that the AVIF example Jake shows is about 37% the size of a regular ol’ JPEG.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s