Skip to main content
    Courses/Markdown/Advanced Markdown Features

    Lesson 5 • Markdown (final lesson)

    Advanced Markdown Features

    By the end of this lesson you'll write GitHub-Flavoured Markdown like a maintainer: footnotes, collapsible sections, escaped characters, raw HTML, anchor-link tables of contents, badges, emoji, and highlighted code — everything a polished README needs.

    What You'll Learn

    • Add footnotes with [^label] and match references to definitions
    • Embed raw HTML (centring, <kbd>, <span style>) inside Markdown
    • Escape special characters with \ to show literal symbols
    • Build collapsible sections with <details> and <summary>
    • Create a table of contents with anchor links, and add shields.io badges
    • Use emoji shortcodes and language-tagged code fences for highlighting

    💡 Real-World Analogy

    Basic Markdown is like a label maker: quick, tidy, perfect for everyday text. GitHub-Flavoured Markdown adds a toolbox — a collapsible drawer (<details>), little reference cards stapled to the back (footnotes), status stickers (badges), and the option to drop in a raw HTML part when the label maker can't do the job. You still write plain text, but now you can build documentation that looks hand-crafted.

    1. Footnotes

    A footnote lets you add a note without cluttering your sentence. You drop a marker like [^1] where the note belongs (the reference), then define it on its own line as [^1]: text (the definition). The label can be a number or a word — what matters is that the reference and definition use the exact same label. When rendered, the marker becomes a small superscript link, and all the notes collect at the bottom of the page.

    Markdown source

    Markdown was created in 2004[^1] and is now everywhere[^docs].
    
    You can even put a footnote mid-sentence[^tip] like this.
    
    [^1]: The original spec was written by John Gruber.
    [^docs]: GitHub, Reddit, and Stack Overflow all use it.
    [^tip]: Labels can be words, not just numbers.

    Rendered result

    Markdown was created in 2004[1] and is now everywhere[docs].

    You can even put a footnote mid-sentence[tip] like this.


    1. [1] The original spec was written by John Gruber. ↩
    2. [docs] GitHub, Reddit, and Stack Overflow all use it. ↩
    3. [tip] Labels can be words, not just numbers. ↩

    2. Embedding Raw HTML

    Markdown can't do everything — there's no syntax for centring text or colouring a word. When you hit that wall, you can drop raw HTML straight into your Markdown and most renderers (GitHub included) will honour it. Common uses: <p align="center"> to centre a logo, <kbd> to style keyboard keys, <br> for a manual line break, and <span style="..."> for inline colour.

    Markdown + HTML source

    Markdown is great, but sometimes you need raw HTML.
    
    <p align="center">
      <strong>Centred text</strong> — Markdown alone can't do this.
    </p>
    
    This text is <span style="color: tomato">tomato-coloured</span>
    and this is <kbd>Ctrl</kbd> + <kbd>C</kbd> in a keyboard tag.
    
    <br>
    
    A manual line break above using the <br> tag.

    Rendered result

    Markdown is great, but sometimes you need raw HTML.

    Centred text — Markdown alone can't do this.

    This text is tomato-coloured and this is Ctrl + C in a keyboard tag.

    A manual line break above using the br tag.

    3. Escaping Special Characters

    Characters like *, _, #, and ` have special meaning in Markdown. To show them literally instead of triggering formatting, put a backslash \ in front. So \*hello\* displays the asterisks instead of turning the word italic. This is the difference between escaping (show the symbol) and literal (the symbol already would have shown) — you only need a backslash when the character would otherwise be interpreted.

    Markdown source

    Show literal Markdown by escaping with a backslash \\ :
    
    \\*not italic\\*   ->  *not italic*   (the asterisks stay visible)
    \\# not a heading -> # not a heading
    \\` not code \\`  ->  ` not code `
    1\\. not a list   ->  1. not a list
    
    Characters you can escape: \\ \` * _ {} [] () # + - . ! |

    Rendered result

    Show literal Markdown by escaping with a backslash \ :

    *not italic*  (the asterisks stay visible)

    # not a heading

    ` not code `

    1. not a list

    4. Collapsible Sections

    A collapsible section hides content behind a clickable label — perfect for long FAQs, solutions, or stack traces. It's raw HTML: wrap the content in <details>, and put the always-visible label in <summary>. The one rule that trips everyone up: leave a blank line after </summary> if you want Markdown (lists, code, bold) to render inside.

    Markdown + HTML source

    ## Troubleshooting
    
    <details>
    <summary>Why won't my footnote render?</summary>
    
    The label after `[^` must match **exactly** between the
    reference and the definition. `[^1]` needs `[^1]:` — not `[^one]:`.
    
    You can use **Markdown** inside a collapsed section, including
    lists and `code`.
    
    </details>

    Rendered result

    Troubleshooting

    Why won't my footnote render?

    The label after [^ must match exactly between the reference and the definition. [^1] needs [^1]: — not [^one]:.

    You can use Markdown inside a collapsed section, including lists and code.

    ↑ Click the triangle to expand it.

    🎯 Your Turn #1: a collapsible FAQ

    Fill in the two blanks so the program prints a valid <details> block, then run it. Notice the blank line that lets Markdown render inside.

    🎯 Your turn: print a collapsible section

    Replace the ___ blanks, run it, then paste the printed source into a GitHub README.

    Try it Yourself »
    JavaScript
    // 🎯 YOUR TURN — build a collapsible FAQ section.
    // Fill in each ___ then press "Try it Yourself" to print your Markdown.
    
    const summaryText = "___";   // 👉 the always-visible label, e.g. "Show the answer"
    const hiddenText  = "___";   // 👉 the text revealed when expanded
    
    console.log("<details>");
    console.log("<summary>" + summaryText + "</summary>");
    console.log("");                       // blank line is REQUIRED for Markdown inside
    console.log(hiddenText);
    console.log("");
    console.log("</
    ...

    5. A Table of Contents with Anchor Links

    Every heading on GitHub automatically gets an invisible anchor (a link target). You can link to it with [Text](#heading). To work out the anchor: take the heading text, make it lowercase, replace spaces with hyphens, and drop punctuation. So ## FAQ & Support becomes #faq--support (the & is dropped, leaving a double hyphen where the spaces were). String these links into a bullet list and you have a clickable table of contents.

    Markdown source

    # Project Handbook
    
    ## Table of Contents
    
    - [Installation](#installation)
    - [Usage](#usage)
    - [FAQ & Support](#faq--support)
    
    ## Installation
    ...
    
    ## Usage
    ...
    
    ## FAQ & Support
    ...

    Rendered result

    Project Handbook

    Table of Contents

    • Installation
    • Usage
    • FAQ & Support

    Each bullet jumps to the matching heading further down the page.

    6. Badges (shields.io)

    Those little status pills at the top of READMEs — build passing, MIT license, version 2.1.0 — are just images. shields.io generates them from a URL, and you embed each one with normal image syntax ![alt](url). The static pattern is .../badge/LABEL-MESSAGE-COLOR.

    Markdown source

    # Awesome Project
    
    ![Build](https://img.shields.io/badge/build-passing-brightgreen)
    ![Version](https://img.shields.io/badge/version-2.1.0-blue)
    ![License](https://img.shields.io/badge/license-MIT-green)
    ![PRs](https://img.shields.io/badge/PRs-welcome-orange)
    
    Pattern: https://img.shields.io/badge/LABEL-MESSAGE-COLOR

    Rendered result

    Awesome Project

    buildpassingversion2.1.0licenseMITPRswelcome

    7. Syntax Highlighting & Emoji

    A fenced code block (three backticks) becomes syntax-highlighted when you write the language name right after the opening backticks — python, json, bash, diff, and dozens more. And emoji shortcodes like :tada: render as 🎉 — handy for friendly headings and changelogs.

    Markdown source

    Tell the fence its language for syntax highlighting:
    
    \`\`\`python
    def greet(name):
        return f"Hello, {name}!"
    \`\`\`
    
    \`\`\`json
    { "name": "ada", "active": true }
    \`\`\`
    
    \`\`\`diff
    + added this line
    - removed this line
    \`\`\`

    Rendered result

    Tell the fence its language for syntax highlighting:

    def greet(name):
        return f"Hello, {name}!"
    { "name": "ada", "active": true }
    + added this line
    - removed this line

    Emoji shortcodes

    :tada: → 🎉   :rocket: → 🚀   :sparkles: → ✨   :bug: → 🐛   :+1: → 👍   :warning: → ⚠️

    Here's a worked example that prints real GFM source you can copy. Run it, read each printed line, then paste it into a GitHub README to watch it render.

    Worked example: print GFM source

    Prints task lists, a footnote, emoji, and a badge as copy-ready Markdown.

    Try it Yourself »
    JavaScript
    // This program PRINTS GitHub-Flavoured Markdown source so you can
    // copy it into a README. The console shows the SOURCE; GitHub shows
    // the RENDERED result (checkboxes, footnote links, emoji).
    
    console.log("=== Task lists (recap) ===");
    console.log("- [x] Create repository");   // renders as a ticked box
    console.log("- [ ] Write the README");    // renders as an empty box
    console.log("");
    
    console.log("=== Footnotes ===");
    console.log("Markdown is everywhere[^1].");
    console.log("[^1]: Used by
    ...

    🎯 Your Turn #2: a matching footnote

    Fill in the blanks so the reference [^label] and the definition [^label]: use the same label. If they don't match, the footnote link breaks — that's the single most common footnote bug.

    🎯 Your turn: print a footnote

    Pick a label and a note; the reference and definition must match exactly.

    Try it Yourself »
    JavaScript
    // 🎯 YOUR TURN — add a footnote. The label in the REFERENCE must match
    // the label in the DEFINITION exactly, or GitHub won't link them.
    
    const label = "___";   // 👉 pick a label WITHOUT the ^, e.g. note  (used as [^note])
    const note  = "___";   // 👉 the footnote text shown at the bottom of the page
    
    console.log("Markdown supports footnotes[^" + label + "].");
    console.log("");
    console.log("[^" + label + "]: " + note);
    
    // ✅ Expected printed source (example, label = "note"):
    //    Markdown su
    ...

    One more runnable tour that prints the source for an anchor-link TOC, escaping, raw HTML, and a highlighted fence — all in one place.

    Advanced patterns recap

    Prints anchor links, escapes, raw HTML, and code-fence tips as source.

    Try it Yourself »
    JavaScript
    // Quick tour of advanced GFM extras (printed as source).
    
    console.log("=== Anchor-link Table of Contents ===");
    console.log("- [Setup](#setup)        // jumps to the '## Setup' heading");
    console.log("- [FAQ & Help](#faq--help)// spaces->-, '&' dropped, lowercased");
    console.log("");
    
    console.log("=== Escaping special characters ===");
    console.log("Type a literal asterisk: \\*not italic\\*");
    console.log("Type a literal hash:     \\# not a heading");
    console.log("");
    
    console.log("=== Raw HTML 
    ...

    Common Errors (and the fix)

    • My raw HTML vanished. The renderer stripped it for safety (npm, some blog engines, comment fields sanitise HTML). It's not a syntax error — test on GitHub, where most HTML is allowed.
    • My footnote isn't a link. The labels don't match. [^1] in the text must pair with [^1]: in the definition — [^1] and [^one]: won't connect.
    • My escape shows the backslash too. You escaped a character that wasn't special, e.g. \a. Only escape Markdown's special characters (\ ` * _ {} [] () # + - . ! |); everywhere else the backslash stays literal.
    • Bold/lists won't render inside my <details>. Add a blank line after </summary>. Without it, the Markdown is treated as raw HTML text.
    • My TOC link goes nowhere. The anchor is wrong. Lowercase the heading, swap spaces for hyphens, drop punctuation: ## My Setup!#my-setup.

    📋 Quick Reference — GFM Extras

    FeatureSyntax
    Footnotetext[^1] … [^1]: note
    Escape\* \# \` \|
    Raw HTML<kbd>Ctrl</kbd>, <br>
    Collapsible<details><summary>…</summary>…</details>
    Anchor link[Setup](#setup)
    Badge![alt](https://img.shields.io/badge/L-M-COLOR)
    Emoji:tada: :rocket: :+1:
    Task list- [ ] todo   - [x] done
    Highlighted code```python … ```

    Mini-Challenge: Build a README Section

    No blanks this time — just a brief and an outline. Use console.log to print the source for a small README that combines four things you learned: a title, a badge, a collapsible install section, and a highlighted code fence. Run it, then paste the output into a GitHub README to see it render.

    🎯 Mini-Challenge: print a mini README

    Print the source for a title, a badge, a <details> install section, and a bash code fence.

    Try it Yourself »
    JavaScript
    // 🎯 MINI-CHALLENGE: print a mini README section
    // Build (with console.log) the SOURCE for a small README that includes:
    //   1. An H1 title line:           # My Tool
    //   2. ONE shields.io badge:       ![License](https://img.shields.io/badge/license-MIT-green)
    //   3. A collapsible "Install" section using <details>/<summary>
    //   4. A fenced \`\`\`bash code block with one install command
    //
    // ✅ Expected printed source (shape):
    //    # My Tool
    //    ![License](https://img.shields.io/badge/lic
    ...

    Pro Tips

    • 💡 Keep HTML minimal. Reach for raw HTML only when Markdown genuinely can't do it (centring, colour, <kbd>) — overusing it makes the source hard to read.
    • 💡 Number footnotes loosely. Labels don't have to be in order; [^a], [^note], [^99] all work as long as each reference has a matching definition.
    • 💡 Test the anchor. Unsure of an anchor? Hover the rendered heading on GitHub — it shows a 🔗 with the exact #anchor.
    • 💡 Collapse noisy content. Long logs, screenshots, and FAQ answers belong in <details> so the README stays scannable.

    Frequently Asked Questions

    Q: Do footnotes and alerts work everywhere?

    No. Footnotes, GitHub alerts, and emoji shortcodes are GFM (or GitHub) extensions. Standard Markdown processors may show [^1] or :tada: as plain text. When in doubt, target GitHub.

    Q: Is it safe to put raw HTML in Markdown?

    On GitHub, basic structural HTML is fine and common. But scripts and many attributes are stripped, and some platforms remove HTML entirely — so don't rely on it for anything that must always appear.

    Q: When do I actually need a backslash?

    Only when a special character would otherwise be interpreted — e.g. a literal * at the start of a word, or a # at the start of a line. Inside normal prose those characters usually render fine without escaping.

    Q: Why won't Markdown render inside my collapsible section?

    You need a blank line after </summary>. With it, GitHub parses the inner content as Markdown; without it, the content is treated as raw HTML.

    Lesson Complete — and you've finished the course! 🎉

    • ✅ Footnotes link a [^label] reference to a matching [^label]: definition
    • ✅ Raw HTML fills Markdown's gaps (centring, <kbd>, colour) — but renderers may strip it
    • ✅ A backslash \ escapes special characters so they show literally
    • <details>/<summary> create collapsible sections (blank line for inner Markdown)
    • ✅ Anchor links [Text](#heading) build a clickable table of contents
    • ✅ shields.io badges, emoji shortcodes, and language-tagged fences polish a README

    Where to go next: put it all to work. Write a real README.md for one of your own projects, or revisit the course overview to review earlier lessons. From here, explore a documentation site generator like MkDocs or Docusaurus — they're powered by the exact Markdown you now know. Congratulations on completing the Markdown course! 📝

    Sign up for free to track which lessons you've completed and get learning reminders.

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service