🍿 3 min. read

Exploring Art Direction With Gatsby-Image

Monica Powell

While updating my homepage to include my newly-commission illustration from Aishwarya Tandon, I wanted to load different versions of the image based on screen-size in a performant way. For my header image, I use gatsby-image, an official GatsbyJS plugin that optimizes images that makes it straightforward to control how images are progressively enhanced on page load. One of my favorite built-in Gatsby image effects is traced SVGs, which renders an SVG tracing of an image, in a pre-determined color before the image fully loads. You can explore all of gatsby-image's built-in loading effects on the using-gatsby-image site.

The above GIF illustrates how gatsby-image transitions from traced SVG to the loaded image

While looking into how to load different images at different breakpoints without unnecessarily downloading files I discovered gatsby-image's built-in support for this feature which is known as art direction. Modern HTML can be used to dynamically load of images based on screen size using srcset attributes with <img> and <source> instead of JavaScript.

The above GIF shows the transition between different images loaded with art direction within gatsby-image

All images that use the gatsby-image plugin need to be constructed using a GraphQL query. Below is a slightly modified version of the useStaticQuery() I used to load image files into gatsby-image's Img. Within useStaticQuery() I wrote two named queries mobileImage and desktopImage to load both versions of the image I wanted on mobile as well as the desktop.

1import React from "react"
2import { useStaticQuery, graphql } from "gatsby"
3import Img from "gatsby-image"
5const Avatar = () => {
6 const data = useStaticQuery(graphql`
7 query {
8 mobileImage: file(
9 relativePath: { eq: "animonica-headshot-cropped.png" }
10 ) {
11 childImageSharp {
12 fluid(maxWidth: 300, quality: 100) {
13 ...GatsbyImageSharpFluid_tracedSVG
14 }
15 }
16 }
17 desktopImage: file(relativePath: { eq: "animonica-full.png" }) {
18 childImageSharp {
19 fluid(maxWidth: 300, quality: 100) {
20 ...GatsbyImageSharpFluid_tracedSVG
21 }
22 }
23 }
24 }
25 `)
27 const sources = [
28 data.mobileImage.childImageSharp.fluid,
29 {
30 ...data.desktopImage.childImageSharp.fluid,
31 media: `(min-width: 625px)`,
32 },
33 ]
35 return <Img fluid={sources} alt="Illustrated Monica" />
38export default Avatar

If you inspect my site's header using Dev Tools you'll notice there's two <picture> sections, one that includes the tracedSVGs that are generated by GatsbyImageSharpFluid_tracedSVG in the image query and another with the .png files.

The HTML that ultimately renders to load the .png files from the earlier use of gatsby-image resembles the below:

2 <source media="(min-width: 625px)" srcset="animonica-full.png" />
3 <source srcset="animonica-headshot-cropped.png" />
4 <img src="animonica-full.png" alt="Illustrated Monica" />

The media attribute in the <source> elements, within <picture>, determines which image srcset is displayed. The first condition that is met will be displayed, in the case where neither media condition is true or the browser doesn't support the <picture> element it will return the <img> element from within the <picture>. You can view current browser compatibility for <picture> at Can I use this?.

As a recap, within gatsby-image we can pass an array of images to generate HTML's art direction related attributes. Using this approach instead of CSS or JavaScript reduces the number of assets that need to be preloaded in the browser. My current Gatsby site, displays a complete HTML page from the server to the client on the initial load without requiring JavaScript therefore I've found it helpful to avoid delegating certain tasks to JavaScript that HTML/CSS can handle in a more performant way. I've written more about this topic in my article Less JavaScript Makes Font Awesome More Awesome.

This article was published on June 24, 2020.

Don't be a stranger! πŸ‘‹πŸΎ

Thanks for reading "Exploring Art Direction With Gatsby-Image". Join my mailing list to be the first to receive my newest web development content, my thoughts on the web and learn about exclusive opportunities.


    I won’t send you spam. Unsubscribe at any time.


    • π™π™šπ™˜π™π™£π™€π™‘π™€π™œπ™žπ™§π™‘
    • Udhay πŸš€ | #AngularHive
    • Mabel
    • Mayara Rysia
    • Oscar 🐻πŸ₯ŒπŸ“·πŸš€πŸ‘πŸ³οΈβ€πŸŒˆπŸ‡ΊπŸ‡ΈπŸ‡²πŸ‡½
    • Xerta
    • Steve
    • Konstantinos Antoniadis
    • JayMa
    • Anisha Pindoria
    • Monty Dawson
    • David Millington
    • YYT
    • Vrymel Omandam
    • Azens Eklak
    • 🀍 Myrka 🀍
    • Matias
    • Yezy Ilomo
    • maxosen74
    • Shek
    • Joe Whitfield-Seed
    • Vicent Gozalbes
    • Ω‚Ψ§Ψ³Ω… Ψ§Ω„ΫŒΨ§Ψ³
    • Erika Donovan
    • Gatare LibΓ¨re
    • Christian
    • Christoph Planken
    • NebojΕ‘a Kamber
    • Erdi
    • Andrew Kolesnikov
    • Emmanuel Adesile
    • Ameem Shaik
    • Samuel Nicholls
    • Ash
    • Agbagosim
    • Ani
    • Jared Jardine
    • Jess Mitchell
    • Aldo AvilΓ©s Perata
    • Alex Kucksdorf
    • +554