The article discusses a method for implementing accessible art direction with Gatsby images and React hooks, focusing on providing alt text for responsive images.
Abstract
The author, who has previously spoken about image handling in Gatsby at the GatsbyNYC meetup, delves into the challenges of art direction with images in Gatsby, particularly the lack of an obvious way to supply alt text for images that change based on breakpoints. To address this, the author proposes a solution using state and custom GraphQL fields to dynamically manage alt text for art-directed images. The article outlines a three-step process: querying images with GraphQL, creating an array of image sources with corresponding media queries, and passing this array to the gatsby-image component. Additionally, the author demonstrates how to use the onLoad prop in the <Img /> component to update the alt text based on the displayed image. The final solution involves attaching alt text to images in the gatsby-node.js file, allowing for reusable and accessible image queries throughout the project.
Opinions
The author emphasizes the importance of accessibility in web development, asserting that inaccessible websites are a result of poor development practices.
They advocate for the use of state and custom GraphQL fields as a practical solution to the problem of dynamic alt text in art-directed images.
The author suggests that hardcoding alt text is not a sustainable approach and instead recommends attaching alt text to images in a way that allows for reuse across the project.
By sharing their approach, the author implies that the current tools and documentation for Gatsby image handling may not be sufficient for ensuring accessibility in art-directed images, necessitating the development of custom solutions.
The article concludes with a promotional note, suggesting that readers who found the content useful might consider trying out a cost-effective AI service called ZAI.chat, which offers similar capabilities to ChatGPT Plus (GPT-4).
Accessible Art Direction with Gatsby Images and React Hooks
I recently gave a talk at the GatsbyNYC meetup about doing art direction with images in Gatsby.
I had spoken at this meetup before about working with images in Gatsby and all of the cool stuff Gatsby does with your images out-of-the-box.
When I started exploring art direction and building an example site for the talk, I realized that there was not an obvious way of supplying alt text to my images.
Since making inaccessible websites is something bad devs do (and I want to be a good dev), I came up with a solution using state and custom Graphql fields.
So, I thought I would share it with you :)
If you want to skip this post and go straight to the repo, that's fine too. The final example is hosted here.
What’s art direction?
Not all images will look good at any size. Some images look great when they are really big, but a bit insipid when they are small. Like this sweeping Icelandic landscape:
Others might look great small, but look weird or get grainy large. Like this pic of Björk:
When your website shows different images based on different break points, this is known as art direction.
How do we do it with Gatsby?
If you have worked with gatsby-image before, this will be very familiar to you. If not, I would suggest following the documentation here to get setup and learn how to render a single image in Gatsby.
To get our images art-directed with Gatsby, we'll follow these steps:
1. Query our images with graphql
2. Create an array of image sources
3. Pass the array to the gatsby <Img /> component
Step 1 - Query the Images
Here, we are querying three images from our filesystem and naming the results reynisfjara, skogafoss, and bjork. We're using the GatsbyImageSharpFluid graphql fragment to get everything we need to create some fluid images. If this part is foreign to you, I recommend going through the documentation and practicing getting some images rendering on your own.
Step 2 - Create an Array of Sources
Now that we have our query, our images will be available in our page component's props in the `data` attribute.
First, we let's pull those images out of props:
Now that we have access to all the image data that we need to give to the <Img /> component, we can create our array of image sources.
Each of the sources is just the result of the GatsbyImageSharpFluid fragment with an added media property.
The media property is going to be a CSS media query that tells the <Img /> component which image needs to be shown at each breakpoint.
We're going to show these images at the following breakpoints:
- Below 701px - bjork
- 701px to 1000px - skogafoss
- Above 1000px - reynisfjara
So, our sources array will look like this:
Great. Now we have our sources array. Let's go to step 3!
Step 3 — Pass the Array to gatbsy-image
Instead of passing a single fluid image result to the <Img /> component as a fluid prop (the way we do for single images), we will pass the sources array to it instead. So let's import the <Img /> component from gatsby-image and do it!
Awesome! We did it. Amazing. We’re done, right?
Nope. Not done. Where’s your alt text?
Ah crap. We got too fancy and now our website is broken. Since we don’t know which image is being shown at any give time, we can’t give it an alt attribute. How are we going to deal with this?
Luckily, the <Img /> component accepts a prop called onLoad that is quite useful. onLoad is a callback function that is going to be called any time an image loads.
Because we are super clever React developers, I bet we can use state to track which image is being shown and update the alt text accordingly. So let’s do that!
First, we setup our state and pass it to the <Img /> component’s alt prop:
Next, we’ll use that onLoad callback to keep track of what the alt text should be. We’ll do this by checking the width of the viewport.
Nice. Crisis averted. Now, our art-directed images have alt text.
Now Are We Done?
Probably not. We solved our problem, but what if we want to reuse those images elsewhere in our project?
All of the alt texts are just hardcoded in our page component. That means we have to re-write those alt texts every time we use those images!
If only there were some way we could attach the alt text to those images themselves. That way, any time we query the image, the alt text would come along for the ride.
Creating Custom Fields in gatsby-node.js
Turns out we can do exactly that using the onCreateNode function in the gatsby-node.js file.
This function is going to get run once as each node on our graph is created. This means any images, markdown files, json files — anything setup as part of our data-layer — is going to trigger this function.
A super handy use of this onCreateNode function is to attach custom fields to our nodes. So for our images, we can attach alt text to them and that alt text can be written once and used anywhere.
So first, let’s just create a basic config object for our images:
Normally, I would put this in its own file and import it into gatsby-node.js, but for simplicity’s sake, we’ll leave it in here for now.
Next, we can use the onCreateNode function to attach these configs to the images:
Now, each of our images has an alt text attached to it. This means that when we query the images with a GraphQL query, the alt text can come along for the ride.
Let’s rewrite our icelandImagesQuery from earlier:
Great! Now let’s use that in place of our hard-coded alt texts.