Oh, hey! It's a "how to write alt text" post. This is something of a rite of passage for accessibility bloggers. That said, I don't rely on alt text in my day-to-day browsing. As such, this post is drawn less from my own lived experience and more from aggregating advice given by blind and low-vision people sharing their own lived experiences and preferences. To learn more, I'd especially recommend Veronica Lewis's guides to writing useful alt text for further guidance.

Posting screenshots of code snippets has become something of a staple for programming educators and advocates on social media. Generally, these snippets are meant to serve as an eye-catching way to illustrate some technique being shared in the post. They can be literal screenshots from an editor or, quite commonly, they're generated with tools such as Carbon.

However, oftentimes, these snippets are shared but their alt text leaves a lot to be desired. Sometimes, it's missing altogether. Other times, it's vague and unusable, like "Code snippet." Either way, blind and low-vision programmers aren't given the opportunity to meaningfully learn from the snippet.

What's the best alt text to provide? Should the alt text just be a copy of the full code? As we'll see, my answer is the classic accessibility mantra: It Depends™.

How Alt Text Is Experienced

The goal of alt text is in its name: to provide a viable alternative, in text form, in place of an image. Someone who reads an image's alt text should generally have the same takeaways as someone who saw the image directly. This is especially critical when the goal of an image is to educate. This means that for screenshots of text, reproducing the text verbatim is often the best alt text.

However, the more text there is to reproduce, the more tedious that wall o’ alt text becomes. Not all screenreaders afford their users the ability to pause an image's alt text readout or to backtrack a few words. Those that do may also add extra clutter the longer the alt text gets. This makes images with very long alt text a commitment, and screenreader users can end up getting lost in the sauce halfway through, faced with the choice to either keep going, start the alt text all over again, or just nope out and skip the rest. This is why, even though screenreaders have no real character limit for alt text these days, it's still important to keep your alt text succinct. Accessibility advocates sometimes suggest a max length of around 120 characters or so as a general rule of thumb, but context will impact how many characters you actually need.

This means your approach to writing alt text for those screenshots of code snippets will probably need to change depending on the length and focus of the snippet.


In a previous version of this post, I said that screenreaders in general don't allow users to pause or traverse alt text. It's since been brought to my attention that I was mistaken — JAWS and NVDA definitely do allow traversing alt text in all the same ways as regular text, but VoiceOver does not seem to. Thanks to Ramón on Twitter as well as Ryan and Roberto at work for pointing this out!

Short, Focused Snippets

If your snippet is only a few short lines long (I'd say maybe five lines or fewer, but as always, It Depends™), and focused on a very particular syntax or technique, then I would reproduce the code exactly for the alt text; no more, no less.

For example, say our post demonstrates how one could use place-items: center to center an element's children:

The snippet:

.centered-children {
display: grid;
place-items: center;

The alt text:

.centered-children { display: grid; place-items: center; }

Beautiful. Nice and tidy. As a sidenote, centering in CSS is awesome these days.

Medium-Length Snippets

Medium-length snippets often establish the relevant syntax or technique in some wider context. This context can be useful to see how the technique would be used in the wild, but it also means that our alt text is veering towards being long enough to be considered a tedious commitment.

In these cases, I like to provide a brief preamble that describes what the snippet is and does, before launching into the code verbatim. Usually, this tends to follow this template or something similar:

[Language or framework name] snippet which demonstrates [relevant syntax or technique] to [provided context]

Then I reproduce the code in full.

This preamble gives screenreader users a handy way to make sense of the code that follows. Crucially, it gives them a handy off-ramp to skip the rest of the alt text if they just can't be bothered.

For example, in a tweet about the <caption> element, I demonstrated <caption> being used inside of a (somewhat truncated) table:

The snippet:

<th scope="col">Rank</th>
<th scope="col">Contestant</th>
<th scope="col">Score</th>


It seemed perfectly sensible to me that a screenreader user might want to nope out after finding out that it depicted markup for a <table> with a <caption>, so I frontloaded the alt text with that context.

The alt text:

HTML snippet for a table with a caption that reads "Leaderboard."

   <th scope="col">Rank</th>
   <th scope="col">Contestant</th>
   <th scope="col">Score</th>

Long-Form Snippets

Long-form snippets contain a lot of text — often well above that general 120-character rule of thumb. In my experience, they're less about demonstrating a specific syntax or technique and more about conveying some bigger-picture idea like a framework component or a full stylesheet. Reproducing the code snippet in full would make the alt text a very tedious slog to get through, with a high chance of the reader getting lost or giving up halfway through.

In these cases, I will generally go with a similar description as I would have for the medium-length snippets, without including the full code in the alt text.

For example, in one tweet, I shared a screenshot I'd found of some cursed Java code where the curly braces and semicolons had been indented to the far right side of the editor to make the code resemble Python's bracelessness and semicolonlessness in an amusingly horrifying way.

public class Permuter																			{
private static void permute(int n, char[] a) {
if (n == 0) {
System.out.println(String.valueOf(a)) ;}
else {
for (int i = 0; i <= n; i++) {
permute(n-1, a) ;
swap(a, n % 2 == 0 ? i : 0, n) ;}}}
private static void swap(char[] a, int i, int j) {
char saved = a[i] ;
a[i] = a[j] ;
a[j] = saved ;}}

In this case, what the code actually did or said didn't matter all that much. It could have been any Java code, really. It just happened to be a Permuter class. Replicating the code in full wouldn't have done the humor of the screenshot any justice. Instead, I kept the alt text very surface-level.

The alt text:

A Permuter class written in Java, but the semicolons and opening and closing braces for each line have been aligned to the far right.

This approach works fine if the code snippet is a little jokey or the exact contents don't really matter. But what do we do if the contents do matter, but they're just a little long?

At this point, lots of readers will be struggling with the size of the snippet. Overzealous image compression will make the code grainy and hard to read. Eager learners who want to try out the code for themselves will have to transcribe a veritable tome of source code by hand. And, of course, screenreader users will still care what the image has to say.

At this point, the most useful thing the poster can do is include a link to the screenshotted code as raw text — often as a GitHub gist — in the body of the post itself. This approach…

  • Allows anyone to copy and paste the code into their own editor to give it a spin
  • Enables screenreader and text-to-speech users to navigate through the code at their own pace
  • Sidesteps the loss of readability that can come from image compression
  • Lets users zoom in to read the code at a more pleasant font size
  • Enables folks to use custom user styles and operating system settings such as forced colors mode to have the viewing/reading experience that works best for them

A picture might be worth a thousand words, but there's a reason why actual raw text is the universal medium.

In cases where I link out to a gist or other text transcription of the code, I like to call it out in the alt text of the image itself, usually by appending something like Full code at the provided link after the aforementioned description of the code's functionality. For example:

A React ThemeToggle component which uses the useTheme hook to switch between light and dark themes. Full code at the provided link.

If a screenreader user wants to access the full snippet, they have the means to get to it. On the other hand, if they don't care, the alt text is now minimally intrusive. We're striking a healthy balance between providng relevant and equivalent information and avoiding needless overwhelm. Nifty.

Warning:URLs don't belong in alt text.

Sometimes, well-meaning posters (and some posters who'd rather the URL not count against their post's character limit) will put the gist URL in the alt text itself. Don't do this! For one thing, the URL won't be actionable when it's read out, so screenreader users won't be able to navigate to it. It'll pretty much just be cumbersome gobbledygook. For another, anyone else who wants to benefit from the raw text version of the code won't be able to get to the link, save for some workarounds involving the social media platform's bespoke alt text pop-ups.


This isn't just about code snippets. Sharing screenshots of hefty bodies of text is absurdly common on social media — be it influencers sharing screenshotted apologies, politicians publishing screenshots of their official statements, or people clipping excerpts of news stories. Oftentimes, these screenshots go undescribed, and when alt text is provided, it's nearly always so vague as to be useless.

Writing alt text that is meaningful and useful remains an artful balance. My hope is that by sharing some of the templates I use, as well as the heuristics and thought processes I run through, someone might get the inspiration they need to describe content they post with a little higher fidelity than "Code snippet."

Chances are really good I've gotten something wrong or didn't take something into account. If that's the case, please reach out on Mastodon. I'd love to hear from you.