Writing Accessible Markdown
Reviewed & published by Brayan K
By the end of this lesson you'll write Markdown that everyone can use — a logical heading outline, descriptive links, meaningful image alt text, proper table headers, and structure that screen readers can convey faithfully.
Part of the free Markdown course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn
- Use one H1 and a logical heading hierarchy without skipping levels
- Write descriptive link text instead of "click here"
- Add meaningful image alt text (and empty alt for decoration)
- Give tables a clear header row so cells are labelled
- Provide enough structure for screen readers to navigate
- Avoid conveying meaning with formatting alone
💡 Real-World Analogy
Accessible Markdown is like reading a document aloud to a friend over the phone. Your friend can't see the page, so "click here" or "look at this" tells them nothing — you'd naturally say "visit the download page". You'd describe a chart instead of saying "nice picture", and you'd read section titles in order so they can follow along. A screen reader is that listener; writing with structure and descriptive words means it can pass on everything a sighted reader sees.
1. A Logical Heading Hierarchy
Headings aren't just big text — they form the outline screen reader users navigate by, jumping from heading to heading. Two rules keep that outline meaningful: use exactly one H1 as the page's single title, and don't skip levels. Go # then ## then ### in order; jumping from an H2 straight to an H4 leaves a gap that breaks the structure.
# Page Title (one H1: the page's single top-level title)
## Getting Started (H2: a major section)
### Install (H3: a subsection of Getting Started)
### Configure (H3: another subsection)
## Troubleshooting (back to H2: a new major section)The outline it creates
- Page Title (H1)
- Getting Started (H2)
- Install (H3)
- Configure (H3)
- Troubleshooting (H2)
A screen reader can jump between these levels to scan the page.
🎯 Your Turn #1: a clean heading outline
Fill in the blanks with the right number of # characters so the program prints one H1, then an H2, then an H3 — no skipped levels.
// 🎯 YOUR TURN — build a correct heading hierarchy.
// Use exactly ONE H1, then go in order (H2, then H3) without skipping.
// Fill in each ___ with the right number of # characters.
const h1 = "___"; // 👉 one # for the single page title
const h2 = "___"; // 👉 two ## for a major section
const h3 = "___"; // 👉 three ### for a subsection of that section
console.log(h1 + " User Guide");
console.log(h2 + " Installation");
console.log(h3 + " Requirements");
// ✅ Expected printed source:
// # User Guide
// ## Installation
// ### Requirements
//
// One H1, then H2, then H3 — a clean outline a screen reader can follow.2. Descriptive Link Text
Many screen reader users pull up a list of all links on a page to navigate. If every link says "click here" or "this", that list is useless. Make link text describe its destination so it stands on its own: [setup steps](setup.md), not "for the setup steps, click here". Good link text helps everyone — it's also clearer for sighted readers scanning the page.
Bad (vague out of context):
For the setup steps, [click here](setup.md).
Good (descriptive, makes sense alone):
Read the [setup steps](setup.md).As a links list (sketch)
Out of context, which is useful?
- ✗ click here (to where?)
- ✓ setup steps (clear)
3. Image Alt Text
Every meaningful image needs alt text — the text in  — that conveys what the image shows to someone who can't see it. Describe the meaning, not the file: "Bar chart: sales doubled from Q1 to Q2" beats "chart.png". For purely decorative images (dividers, spacers) use empty alt  so screen readers skip them rather than announcing a useless filename.
Meaningful image (describe its content):

Decorative image (empty alt so it is skipped):
What a screen reader announces
✓ "Image: Bar chart: sales doubled from Q1 to Q2"
✓ (decorative image, with empty alt) — skipped silently
A missing alt would make some readers announce the filename instead, which is just noise.
Here's a worked example that prints accessible Markdown source. Run it, read each printed line, then notice how the structure, one H1, ordered levels, descriptive links, and real alt text, is what makes it usable for everyone.
## One H1, then ordered levels
# Quarterly Report
## Summary
### Highlights
## Descriptive link text
See the [full results](results.md).
## Alt text that conveys meaning


<!-- ✅ Expected result, rendered:
h2 -> text: One H1, then ordered levels
h1 -> count: 1
h2 -> count: 4
h3 -> count: 1
p -> count: 2
a -> count: 1
img -> count: 2
-->🎯 Your Turn #2: descriptive link and alt text
Fill in the blanks so the program prints a link with descriptive text and an image with meaningful alt text. Avoid "click here" and avoid empty alt for a meaningful image.
// 🎯 YOUR TURN — write DESCRIPTIVE link text and ALT text.
// Link text should make sense on its own; alt text should convey the
// image's meaning. Fill in each ___.
const linkText = "___"; // 👉 describe the destination, e.g. download page
const altText = "___"; // 👉 describe the image, e.g. Screenshot of the app
console.log("Visit the [" + linkText + "](download.html).");
console.log("");
// ✅ Expected printed source (example):
// Visit the [download page](download.html).
// 
//
// Avoid "click here" and avoid empty alt for a meaningful image.4. Table Headers and Honest Formatting
Give every table a clear header row so assistive tech can associate each data cell with its column — it can announce "Capital: Paris" rather than a lone "Paris". And never rely on formatting alone to carry meaning: if "items in bold are required", a user who can't perceive the bold misses it entirely. State the meaning in words (mark required items with the word "required") so it survives without the styling.
| Country | Capital |
|---------|----------|
| France | Paris |
| Japan | Tokyo |
The header row (Country, Capital) lets a screen reader announce
each cell with its column name, e.g. "Capital: Paris".Why the header row matters
| Country | Capital |
|---|---|
| France | Paris |
| Japan | Tokyo |
Each cell is announced with its column name, e.g. "Capital: Paris".
Common Errors (and the fix)
- Multiple H1s or a skipped level. Use one H1 and step through levels in order; don't jump H2 to H4.
- "Click here" links. Replace with text that names the destination, like [API reference](api.md).
- Missing or unhelpful alt text. Add alt that conveys meaning; use empty alt only for decorative images.
- Headerless table. Always include the header row so columns are labelled for assistive tech.
- Meaning hidden in styling. "Bold = required" fails for anyone who can't see bold. Say "required" in the text.
📋 Quick Reference — Accessibility
| Do | Instead of |
|---|---|
| One H1, ordered levels | Several H1s or skipped levels |
| [setup steps](setup.md) | [click here](setup.md) |
|  |  for a meaningful image |
|  for decoration |  |
| Table with a header row | A table with no header |
| "required" stated in words | Meaning shown by bold alone |
Mini-Challenge: An Accessible Mini-Document
No blanks this time — just a brief and an outline. Use console.log to print the source for a short page with one H1, ordered H2/H3 sections, a descriptive link, a meaningful image with alt text, and a small table with a header row.
// 🎯 MINI-CHALLENGE: print an accessible mini-document.
// Build (with console.log) the SOURCE for a short page that includes:
// 1. Exactly ONE H1 title
// 2. Two H2 sections, and one H3 under the first (no skipped levels)
// 3. One link with DESCRIPTIVE text (not "click here")
// 4. One meaningful image with ALT text that conveys its content
// 5. A small table WITH a header row
//
// ✅ The result should read as a clean outline with descriptive links,
// real alt text, and a table whose header row labels the columns.
// your code herePro Tips
- 💡 Read your links aloud. If a link's text makes no sense without the sentence around it, rewrite it to name the destination.
- 💡 Describe the message, not the medium. Alt text should capture what a chart says ("sales doubled"), not that it's an image.
- 💡 Outline first. Sketch your H1/H2/H3 structure before writing; a clean outline is easier to keep accessible.
- 💡 Use real lists and tables. Genuine Markdown lists and tables give assistive tech structure that manual spacing or line breaks never will.
Frequently Asked Questions
Q: Does Markdown become accessible automatically?
Markdown produces real HTML headings, lists, and links, which is a great start. But meaning depends on you: descriptive link text, alt text, header rows, and a correct heading order.
Q: When should alt text be empty?
Only when the image is purely decorative and conveys no information. Empty alt tells screen readers to skip it; a meaningful image always needs descriptive alt.
Q: Is it really a problem to skip a heading level?
Yes. Users who navigate by headings rely on the order; a gap (H2 to H4) breaks the outline and makes the structure confusing.
Q: How do I emphasise something accessibly?
Use emphasis for visual weight, but also make the meaning explicit in words, so it isn't lost for anyone who can't perceive the styling.
Lesson Complete — and you've finished the course! 🎉
- ✅ Use one H1 and step through heading levels in order, never skipping
- ✅ Write descriptive link text, not "click here"
- ✅ Give meaningful images real alt text; use empty alt for decoration
- ✅ Include a header row so table cells are associated with their columns
- ✅ State meaning in words rather than relying on bold or colour alone
Where to go next: revisit the course overview to review earlier lessons, then apply these habits to a real README or docs site. Congratulations on completing the Markdown course! 📝
Practice quiz
How many top-level (H1) headings should a page normally have?
- Exactly one
- As many as you like
- At least three
- Zero
Answer: Exactly one. A single H1 gives the page one clear title; screen readers and outlines rely on that one top-level heading.
Why should you avoid skipping heading levels (for example H2 to H4)?
- It hides the text
- It changes the font colour
- It breaks the logical outline that assistive tech relies on
- It is a syntax error
Answer: It breaks the logical outline that assistive tech relies on. Skipping levels confuses the document outline that screen reader users navigate by; go in order H2, then H3.
Which link text is the most accessible?
- this
- Read the installation guide
- link
- click here
Answer: Read the installation guide. Descriptive link text makes sense out of context, which helps users who navigate by jumping between links.
What should an image's alt text describe?
- The file size
- The camera model
- The file format
- The image's meaning or content for someone who cannot see it
Answer: The image's meaning or content for someone who cannot see it. Alt text conveys the image's purpose or content so screen reader users get the same information.
When is empty alt text (alt="") appropriate for an image?
- For purely decorative images that add no information
- For every image
- Never
- Only for logos
Answer: For purely decorative images that add no information. Decorative images that carry no meaning take empty alt text so screen readers skip them rather than reading noise.
What makes a Markdown table more accessible?
- Coloured cells
- Having a clear header row so cells are associated with headers
- Removing the separator row
- Using only one column
Answer: Having a clear header row so cells are associated with headers. A proper header row lets assistive tech announce each data cell with its column heading.
Why shouldn't you rely on bold or colour alone to convey meaning?
- It increases file size
- It is slower to type
- Bold is not valid Markdown
- Users who can't perceive the styling miss the meaning
Answer: Users who can't perceive the styling miss the meaning. Meaning carried only by formatting is lost to people who can't see the emphasis; state it in words too.
What is the accessibility benefit of a logical heading hierarchy?
- It changes the page language
- It hides headings from search engines
- It lets users jump through the document structure with a screen reader
- It compiles faster
Answer: It lets users jump through the document structure with a screen reader. A correct hierarchy creates a navigable outline, so users can move by heading level to find sections quickly.
Which is the better approach for a meaningful image in documentation?
- Omit the alt attribute entirely
- Write concise alt text that conveys its purpose
- Use the filename as alt text
- Set alt to the word image
Answer: Write concise alt text that conveys its purpose. Concise, purposeful alt text communicates what the image shows; filenames and generic words are not helpful.
Good Markdown structure for screen readers means primarily what?
- Real headings, lists, and link text rather than visual tricks
- Avoiding all headings
- Writing everything in one paragraph
- Using as many emojis as possible
Answer: Real headings, lists, and link text rather than visual tricks. Semantic structure, true headings, real lists, and descriptive links, gives assistive tech something meaningful to convey.
Continue this course
- Previous: Publishing with MkDocs, Hugo and Jekyll
- Quick reference: Markdown cheat sheet