Markdown Hacks: Workarounds for Missing Features
Markdown hacks are HTML snippets and creative syntax tricks that produce features the core markdown spec leaves out, from underlined text to clickable video thumbnails. Nearly every hack depends on one condition: the renderer must accept inline HTML. CommonMark passes raw HTML through by default, so VS Code, Obsidian, Typora, and this site's editor display these workarounds correctly. Sanitized platforms behave differently. GitHub filters output through a fixed tag allowlist and deletes every style attribute, while Reddit and Discord ignore HTML completely. Each section below shows the syntax and lists the renderers that keep or strip it.
Underline Text
Markdown has no underline syntax, so wrap the text in an HTML <ins> or <u> tag. The <ins> tag marks inserted text and renders with an underline in every major browser. GitHub's sanitizer keeps <ins> and drops <u>, so <ins> is the portable choice for READMEs.
Submit the form <ins>before 30 June</ins> to qualify.
Obsidian and Typora render both tags. Bear and Simplenote skip the HTML route and offer their own underline shortcuts. On Reddit the tags appear as literal text because its parser discards HTML.
Indent Paragraphs
Markdown collapses leading spaces and converts 4-space indents into code blocks, so indent a paragraph with the non-breaking space entity instead. Each entity survives as one visible space in the output. Four of them fake a classic tab stop.
The opening line of this paragraph sits four spaces in.
Entities pass through almost every renderer, GitHub included, because they are character references rather than tags. The limit shows at scale. A document with dozens of indented paragraphs becomes hard to read in source form, and an editor with template control, such as iA Writer, handles indentation more cleanly.
Center Text
Center a line with the <center> tag, or with <p style="text-align:center"> where inline CSS survives. HTML 4.01 deprecated <center> back in 1999, yet browsers still honor it and most markdown renderers pass it through untouched.
<center>Chapter 7</center>
<p style="text-align:center">Chapter 7</p>
GitHub deletes style attributes, so the second form fails there. README authors center logos and badges with <div align="center"> instead, because the align attribute survives GitHub's sanitizer. Typora and the VS Code preview both render the CSS version as written.
Color Text
Markdown offers no text color control; use <span style="color:#0969da"> where CSS is allowed, or the old <font color="red"> tag in renderers that still accept it.
<span style="color:#0969da">This sentence renders in blue.</span>
<font color="red">This sentence renders in red.</font>
The <font> tag was deprecated in 1999 and modern sanitizers treat it harshly. GitHub strips the style attribute and the color attribute alike, so neither form produces colored text in a README. A common substitute there is a fenced code block with diff as the language, which paints lines that start with + green and lines that start with - red. Obsidian and Typora honor the <span> version, as do Hugo and Jekyll sites that pass raw HTML through.
Hide Comments
Hide a note from readers with the link-reference trick [comment]: # or with a standard HTML comment. Both keep text in the source file and out of the rendered page.
[everything in this line disappears from the output]: #
<!-- This note also stays hidden. -->
The bracket trick abuses link reference definitions, a core markdown feature, so it works even where HTML is blocked. Put a blank line above and below it or an adjacent paragraph may merge into the definition. The HTML comment is easier to read but remains inside the generated page source, where anyone can view it. GitHub honors both methods.
Admonitions and Callout Boxes
Create a callout box with an emoji and a bold label inside a blockquote, or use GitHub's alert syntax, introduced in 2023.
> [!WARNING]
> This command overwrites all 14 archived backups.
> 💡 **Tip:** Blockquote callouts work in any renderer.
GitHub supports 5 alert types: NOTE, TIP, IMPORTANT, WARNING, and CAUTION. Each renders with its own icon and accent color on github.com, but the syntax degrades to a plain blockquote everywhere else. Obsidian has a separate callout format, > [!note], added in version 0.14 in 2022, and MkDocs with the Material theme uses !!! note lines. The emoji blockquote is the only variant that looks acceptable across all of them.
Resize Images
Swap the markdown image syntax for an <img> tag and set the width and height attributes in pixels.
<img src="diagram.png" alt="Deployment diagram" width="480" height="270">
GitHub keeps width and height attributes even though it strips style="width:50%", so pixel values are the reliable path for READMEs. Fixed dimensions also prevent layout shift while the page loads. Renderers without HTML support display the raw tag as text, so keep the plain  form on platforms such as Reddit.
Image Captions
Add a caption with the <figure> and <figcaption> tags, or place an italic line directly under the image.
<figure>
<img src="harbor.jpg" alt="Fishing boats at dawn">
<figcaption>Hobart's harbor, photographed in March 2025.</figcaption>
</figure>

*Hobart's harbor, photographed in March 2025.*
Both <figure> and <figcaption> sit on GitHub's allowlist, so the semantic version works in READMEs. The italic line is the fallback for HTML-free renderers. Screen readers announce it as body text rather than a caption, which is the trade-off for its portability.
Links That Open in a New Tab
Markdown links cannot open in a new tab; write the anchor in raw HTML with target="_blank" instead.
<a href="https://example.com/report" target="_blank" rel="noopener">2026 annual report</a>
Add rel="noopener" so the new page cannot script against the window that opened it. This hack has a short reach. GitHub removes the target attribute during sanitization, and every README link opens in the same tab regardless. The trick works in static site generators such as Hugo and Jekyll, which pass HTML through untouched, and that is where new-tab behavior matters most.
Symbols and Special Characters
Type symbols directly, since markdown files are plain Unicode text, or use HTML entities when a symbol is hard to reach from the keyboard. Copy © or → from any character reference page and paste it into the file; it renders unchanged.
| Symbol | HTML entity |
|---|---|
| © copyright | © |
| ® registered | ® |
| ™ trademark | ™ |
| → right arrow | → |
| ° degree | ° |
| € euro | € |
Entities convert in nearly every renderer, GitHub included. The one trap is code blocks, where © prints literally because fenced code disables entity decoding.
Table of Contents
Build a table of contents as a bulleted list of links that point at heading anchor IDs. GitHub, GitLab, and most other renderers generate an ID for every heading: the text is lowercased and spaces become hyphens, with most punctuation removed.
- [Underline Text](#underline-text)
- [Resize Images](#resize-images)
- [Embed Videos](#embed-videos)
A heading named "Resize Images" gets the anchor #resize-images. GitHub has also shown an automatic TOC button on README headers since 2021, so a manual list earns its keep in long documents on other platforms. Recheck the anchors after every heading edit, because a renamed heading silently breaks its links.
Embed Videos
Markdown cannot embed a video player, so link a clickable thumbnail image to the video instead. YouTube publishes a thumbnail for every video at a predictable URL, which makes the pattern simple.
[](https://www.youtube.com/watch?v=VIDEO-ID)
Replace VIDEO-ID with the 11-character code from the video URL. The thumbnail renders anywhere standard markdown works, and a click opens the video on YouTube. Two upgrades exist where the platform allows them. GitHub has accepted direct .mp4 and .mov uploads in issues, pull requests, discussions, and markdown files since May 2021, and renderers with full HTML support accept a pasted YouTube <iframe> embed.
Frequently asked questions
Do markdown hacks work on GitHub?
Some do. GitHub keeps <ins>, <img> width attributes, <figure>, HTML comments, entities, and its own alert syntax, but it strips every style attribute and the target attribute. Test any hack in a draft gist before you depend on it, because the sanitizer allowlist can change without notice.
Why did my HTML disappear from the rendered page?
The renderer either blocks inline HTML entirely, as Reddit and Discord do, or removed the specific tag or attribute you used during sanitization. Check the platform's documentation for an allowlist, then swap the stripped element for a permitted one, such as <div align="center"> in place of a style attribute.
Which comment style is better, [comment]: # or <!-- -->?
Use [comment]: # when the note must vanish completely, and <!-- --> when source readability matters more. The bracket form is consumed by the markdown parser and never reaches the output, while a standard HTML comment stays visible to anyone who views the page source.
