How to create accessible GitHub Markdown files
Last updated: August 18, 2025
This guide explains how to create Markdown files on GitHub that are accessible to assistive technology users.
About GitHub Markdown files
Markdown is a markup language used to create formatted text. Markdown files are easy to read and write by both humans and computers.
In VA GitHub repositories, we use Markdown to create documentation, such as research plans, conversation guides, research reports, and readme files. The Accessibility Digital Experience team’s readme page is one example.
To learn more about creating GitHub Markdown files, read GitHub’s documentation, starting with Quickstart for writing on GitHub.
Accessible GitHub Markdown best practices
Use headings, not bolded text
Many assistive technology users navigate web pages by heading. They may access a list of headings on the page and pick the one they’re interested in, or use a shortcut to jump between headings. Bolded text may look like a heading, but it isn’t conveyed as a heading to assistive technology.
Use the pound sign, #
, to create headings and subheadings in Markdown. The number of pound signs represents the heading level - #
for level 1, ##
for level 2, etc.
Do this:
## My heading
Not this:
**Not a heading**
Create a logical heading structure.
Do this:
### My favorite things
#### Books
Not this:
### My favorite things
##### Books
Why not? Because there’s a level 3 but not a level 4 before the level 5
Create meaningful alt text for every image
Every image in a Markdown file needs a meaningful text description, or “alt text,” so that users who can’t see the image have equal access to its information.
When you link to an image, use either of these formats:
[your alt text](image URL)
<image alt=”your alt text” src=”image URL”>
In GitHub, If you upload an image directly to the file or comment, it creates code in this format: <image width=”” height=”” alt=”Image” src=”image URL”>
. Replace “Image” with meaningful alt text.
Do this:
[VA Profile user interface. The View payment history link has focus.](image URL)
Not this:
[](image URL)
Why not? Because the alt text is missing
Do this:
<image alt=”Research participant accesses VA.gov on their iPhone” src=”image URL”>
Not this:
<image alt=”Image” src=”image URL”>
Why not? Because alt text needs to be more specific than the word “Image”
Create unique, descriptive text for each link
Many screen reader users navigate web pages by either tabbing through interactive elements or selecting from a list of the links on the page. Because of this, every link must be able to stand on its own without any of the surrounding content. And the link text must be unique and tell the user what to expect if they follow the link.
1. Describe what the link is for
Keep the link as short as possible while being descriptive.
Do this: Review the Links vs buttons page
Markdown:
Review the [Links vs buttons page](URL)
Why is this OK? Because the link text includes the title of the page
Or this: Review VA guidance about links
Markdown:
Review [VA guidance about links](URL)
Why is this OK? Because the link text specifies the subject matter of the page
Not this: Review VA guidance about links
Markdown:
Review [VA guidance](URL) about links
Why not? Because the link text doesn’t specify the subject of the VA guidance
2. Provide context
The link must be understandable on its own without any of the surrounding content.
Do this: Figure 1 - quotes about the user interface
Markdown:
[Figure 1 - quotes about the user interface](URL)
Why is this OK? Because the link text contains the context
Not this: Figure 1 (quotes about the user interface)
Markdown:
[Figure 1](URL) (quotes about the user interface)
Why not? Because the “Figure 1” link doesn’t contain any context
3. Create unique text for each link
Every link needs to be distinct from all other links on the page.
Do this:
CODE[Edit personal information](URL) [Edit address](URL)
Not this:
CODEPersonal information: [Edit](URL) Address: [Edit](URL)
Why not? Because the links are identical and don’t tell you what you’re editing
4. Tell users if the link takes them to something that’s not a web page
If the link takes the user to a file (e.g., an image, PDF, or Word document), put that information in the link text.
Do this: Figure 1 - sample benefit letter (PDF)
Markdown:
[Figure 1 - sample benefit letter (PDF)](URL)
Or this: Figure 1 - sample benefit letter (image)
Markdown:
[Figure 1 - sample benefit letter (image)](URL)
Or this: Changed the XX button (Figure 2 shows the new YY button)
Markdown:
Changed the XX button ([Figure 2 shows the new YY button](URL))
Why is this OK? Because the word “Figure” implies “image”
Or this: Screenshot of the magnification issue in Figure 3.
Markdown:
<details><summary>Screenshot of the magnification issue in Figure 3</summary>
Why is this OK? Because the word “screenshot” implies “image”
Not this: Figure 1 - sample benefit letter
Markdown:
[Figure 1 - sample benefit letter](URL)
Why not? Because the link doesn’t specify that it’s linking to an image
Use disclosure widgets correctly
Markdown allows the use of <details>
and <summary>
. This creates a disclosure widget; the content within <summary>
is the toggle button.
Example:
<details>
<summary>My disclosure widget</summary>
Now it's open!
</details>
Disclosure widgets come with tradeoffs:
Long pages can be overwhelming to read and hard to scan. Disclosure widgets can reduce visual and mental clutter.
Users can miss information when it’s hidden in a disclosure widget.
Some assistive technologies don’t properly announce
<details>
and<summary>
state changes, such as when the widget is open or closed.
It’s important to use disclosure widgets thoughtfully and only when necessary. For example, in a research report, an illustrative screenshot could be placed in a disclosure widget if it impedes the report’s scannability or is tangential to the rest of the content.
Before deciding to use a disclosure widget, ask yourself these questions:
Does this information need to be on the page?
If yes, does the information need to be hidden? Why?
If yes, use a disclosure widget. Each use of
<summary>
should have a unique, meaningful name that describes the content and not the action required to open it (e.g., “click to open”).Do this:
CODE<details> <summary>Findings</summary> Content about findings </details> <details> <summary>Participant demographics</summary> Content about participant demographics </details>
Why is this OK? Because the
<summary>
is unique and descriptive for each disclosure widget
Not this:
CODE<details> <summary>Details</summary> Content about findings </details> <details> <summary>Details</summary> Content about participant demographics </details>
Why not? Because the
<summary>
is identical for the two disclosure widgets
Do this:
CODE<details> <summary>Screenshot of the link magnification issue in Figure 3</summary> Content </details>
Not this:
CODE<details> <summary>Click to see a screenshot of the link magnification issue in Figure 3</summary> Content </details>
Why not? Because words like “click”, “expand”, “reveal”, and “show” duplicate the state information already announced by screen readers.
Use anchor links in long documents
It can be helpful to add anchor links to long documents to help users jump to the specific section they’re interested in. Think of these like an in-page table of contents:
GitHub automatically generates section heading links (e.g., #key-findings
for ## Key findings
). However, due to a GitHub bug, these links aren’t accessible because they don’t move focus to the heading when navigating by keyboard. To accommodate this, we recommend linking to the “chain link” icon rather than the heading itself.
Follow these steps to create a set of accessible anchor links in a GitHub-rendered Markdown file:
Create your content using semantic headings (
#
,##
, etc.)Publish the page
Find the anchor you want to link to:
Tab to or hover over the heading you want to make a link for. You’ll notice a “chain link” icon:
Select the icon. In the URL bar, copy what comes after the pound sign:
...research-report.md#key-findings
.Add “
user-content-
” before that:#user-content-key-findings
, in this example.
Once you have all the anchors you want to link to, create a bulleted list near the top of your document. Link to the anchor link constructed in step 3. Use the heading text as the link text:
- [Key findings](#user-content-key-findings)
- [Recommendations](#user-content-recommendations)
Help and feedback
Get help from the Platform Support Team in Slack.
Submit a feature idea to the Platform.