Inline HTML
Write raw HTML directly in your markdown files. sitemd passes all HTML through to the final page with no sanitization or filtering — what you write is what renders.
Inline elements
Use HTML tags inside a paragraph alongside regular markdown:
This word is <mark>highlighted</mark> and this is <kbd>Ctrl+C</kbd>.
Water is H<sub>2</sub>O. The equation is E = mc<sup>2</sup>.
Use <abbr title="Hypertext Markup Language">HTML</abbr> when markdown isn't enough.
Common inline tags: <span>, <mark>, <kbd>, <abbr>, <sub>, <sup>, <small>, <del>, <ins>.
Block elements
Block-level HTML goes on its own line with blank lines above and below:
Some markdown text above.
<div style="padding: 1rem; border-left: 3px solid var(--accent); background: var(--bg-secondary);">
<strong>Note:</strong> This is a custom callout box using theme CSS variables.
</div>
More markdown text below.
The blank lines are important — without them, markdown won't recognize where the HTML block starts and ends.
Collapsible sections
The <details> and <summary> elements create expandable sections:
<details>
<summary>Click to expand</summary>
This content is hidden by default. You can use **markdown** inside the details block — just leave a blank line after the `<summary>` tag.
- Lists work
- So do `code blocks`
- And [links](/)
</details>
Click to expand
This content is hidden by default. You can use markdown inside the details block — just leave a blank line after the <summary> tag.
- Lists work
- So do
code blocks - And links
Add the open attribute to start expanded: <details open>.
Embedding media
For common providers like YouTube, Vimeo, and Spotify, the embed syntax is simpler — just embed: URL on its own line. Use inline HTML when you need full control over iframe attributes.
Embed videos, iframes, or any external content:
<video controls width="100%">
<source src="/theme/videos/demo.mp4" type="video/mp4">
</video>
<iframe src="https://www.youtube.com/embed/VIDEO_ID"
width="100%" height="400" frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media"
allowfullscreen></iframe>
Styling with theme variables
Inline styles can reference sitemd's CSS custom properties for consistent theming across light, dark, and paper modes:
<div style="color: var(--accent); border: 1px solid var(--border); padding: 1rem; border-radius: 8px;">
This box adapts to the current theme mode automatically.
</div>
Commonly used variables:
| Variable | What it is |
|---|---|
--accent |
Theme accent color |
--text |
Primary text color |
--text-secondary |
Muted text color |
--bg |
Page background |
--bg-secondary |
Subtle background (cards, callouts) |
--border |
Border color |
Mixing HTML and markdown
Markdown inside block-level HTML works if you leave blank lines between the HTML tags and the markdown content:
<div class="two-column" style="display: grid; grid-template-columns: 1fr 1fr; gap: 2rem;">
<div>
**Left column** with markdown content, lists, and [links](/).
</div>
<div>
**Right column** with completely different content.
</div>
</div>
Without the blank lines, the content inside the tags is treated as raw HTML and markdown syntax won't be processed.
Scripts
Inline <script> tags work the same as any other HTML — they execute when the page renders.
<div id="counter">0</div>
<script>
(function() {
var el = document.getElementById('counter');
var count = 0;
el.addEventListener('click', function() {
count++;
el.textContent = count;
});
})();
</script>
SPA navigation vs. full page loads
sitemd uses SPA-style navigation for internal links — clicking a link swaps the page content without a full reload. Inline scripts in the new page are re-executed after the swap.
On a full page load (direct URL, refresh, or external link), window.__sitemdAuth exists (auth.js loads in the <head>), but auth initialization is async — session recovery and magic link callbacks may still be in progress.
To safely depend on the auth API, wait for auth.ready:
(function() {
function init() {
var auth = window.__sitemdAuth;
// auth is guaranteed to be available here
}
if (window.__sitemdAuth) window.__sitemdAuth.ready.then(init);
else document.addEventListener('sitemd:auth-ready', init);
})();
This pattern works in both cases — on SPA navigation auth.ready is already resolved and init() runs on the next microtick; on a full page load it waits for initialization to complete.
Notes
- No sanitization — HTML renders exactly as written. This gives you full control but means you're responsible for valid markup.
- Theme awareness — use CSS variables instead of hardcoded colors so your HTML works across all three theme modes.
- Code blocks are safe — HTML inside fenced code blocks is displayed as code, not rendered.