Gatsby icon
• 🥨 4 min read

Exploring Art Direction With Gatsby-Image

Animated Monica

By: 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.

import React from "react";
import { useStaticQuery, graphql } from "gatsby";
import Img from "gatsby-image";

const Avatar = () => {
  const data = useStaticQuery(graphql`
    query {
      mobileImage: file(
        relativePath: { eq: "animonica-headshot-cropped.png" }
      ) {
        childImageSharp {
          fluid(maxWidth: 300, quality: 100) {
            ...GatsbyImageSharpFluid_tracedSVG
          }
        }
      }
      desktopImage: file(relativePath: { eq: "animonica-full.png" }) {
        childImageSharp {
          fluid(maxWidth: 300, quality: 100) {
            ...GatsbyImageSharpFluid_tracedSVG
          }
        }
      }
    }
  `);

  const sources = [
    data.mobileImage.childImageSharp.fluid,
    {
      ...data.desktopImage.childImageSharp.fluid,
      media: `(min-width: 625px)`,
    },
  ];

  return <Img fluid={sources} alt="Illustrated Monica" />;
};

export 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:

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

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.

Likes & Reposts

Shared by GatsbyShared by MaxShared by theworstdevShared by KyleShared by forgrimmShared by AndreyShared by JohnShared by :party-corgi:Shared by RichShared by AbdelShared by JustinShared by cloudsh

+655

Discussion

  • mentioned on March 18, 2025
    via ohhelloana.blog

    in Other bookmarks from May and June

  • mentioned on February 12, 2021
    via

    After fighting with my images for the past few days I found this article by @indigitalcolor and I only wish I'd found it sooner! aboutmonica.com/blog/2020-06-2…

  • replied on July 1, 2020
    via

    There's not enough pink on websites, I love your site!

  • mentioned on June 26, 2020
    via

    super cool!

  • mentioned on June 26, 2020
    via

    Okay that's 🔥 ngl

  • replied on June 25, 2020
    via

    Awesome stuff. I feel like mastering art-directed, responsive images with good performance is like getting a black-belt in FE wizardry.

  • replied on June 25, 2020
    via

    Wow that’s really cool

  • replied on June 25, 2020
    via

    wow! that is cool. thanks!

  • mentioned on June 25, 2020
    via

    This is the kind of attention to detail that you should look for when hiring your next your #webdeveloper

  • replied on June 25, 2020
    via

    I might explore adding an intermediate file but it would also be cool to look into the gradual clipping approach. I think this is the coolest thing I've seen with media queries: twitter.com/sarah_edo/stat…

  • replied on June 25, 2020
    via

    That was very informative. Thanks for sharing, and it looks awesome!

  • replied on June 25, 2020
    via

    Beautiful site!

  • replied on June 25, 2020
    via

    Nice!!!

  • replied on June 25, 2020
    via

    Looks great!!!

  • mentioned on June 25, 2020
    via

    You up on this, @TechLifeSteph? This feels like is could be destined for a #60secondtechbreak

  • replied on June 25, 2020
    via

    Double take levels of awesome.

  • replied on June 25, 2020
    via

    Thank you Shanice 😊

  • replied on June 25, 2020
    via

    Love it!

  • replied on June 25, 2020
    via

    This is awesome, way to go Monica 👏🏾👏🏾

  • mentioned on June 24, 2020
    via

    This article is sooo good! I don't have images on my site but I have them on others sites I own. Def gonna utilize this! 😍

  • replied on June 24, 2020
    via

    Thank you, I will bookmark this. I've stumbled in the past over the various incantations for loading images in Gatsby.

  • replied on June 24, 2020
    via

    This is awesome, Monica. Great writeup and examples. The site looks AMAZING!

  • replied on June 24, 2020
    via

    Thanks for the blogpost! That's really awesome. Didn't know about the SVG tracing 🤯