Styling
Set theme variables for a whole document, or target individual elements with CSS. MarkdownViewer, MarkdownRenderer, and MarkdownStream share the same element classes.
Setup
Pass a class to the component and place overrides in your stylesheet. No package stylesheet or Tailwind
configuration is required. In a Svelte <style> block, use :global(...) so selectors reach
the child renderer's markup.
<script lang="ts">
import { MarkdownViewer } from 'markdown-svelte'
const source = '# Hello, **Svelte**!'
</script>
<MarkdownViewer markdown={source} class="document" />
<!-- Or: <MarkdownStream {nodes} class="document" /> -->
<style>
:global(.document) {
--markdown-color-text: #292b29;
--markdown-color-link: #a63f24;
--markdown-color-surface: #f3f4ee;
--markdown-radius: 0;
--markdown-font-sans: system-ui, sans-serif;
font-size: 1.05rem;
line-height: 1.8;
}
:global(.document .markdown-svelte-heading--2) {
border-bottom: 0;
font-family: Georgia, serif;
}
</style> In a global CSS file, omit :global(...). The examples below use that form. Base element styles use :where(...) to keep specificity low, so ordinary class selectors can override them. Existing app styles
for tags such as a or code can also take precedence; use a scoped element selector when needed.
Theme variables
Set these on the component's class or an ancestor. Font size, line height, spacing, and document background use normal CSS properties. The default palette is light; set colors explicitly for a dark surface.
| Variable | Default | Applies to |
|---|---|---|
--markdown-color-text | #253044 | Document text. |
--markdown-color-muted | #667085 | Secondary text, blockquotes, and fallback labels. |
--markdown-color-border | #d7dde7 | Rules, table borders, and element outlines. |
--markdown-color-surface | #f5f7fa | Blockquotes, containers, and math blocks. |
--markdown-color-surface-strong | #e9edf3 | Table headers. |
--markdown-color-link | #0b62c4 | Links and footnote navigation. |
--markdown-color-accent | #087164 | Blockquote borders, checkboxes, and default admonitions. |
--markdown-color-code | #e8edf5 | Inline code and inline math backgrounds. |
--markdown-code-background | #111827 | Fenced code block background. |
--markdown-code-text | #e5edf8 | Fenced code block text. |
--markdown-radius | 0.55rem | Block, table, and image corners. Inline code and math have their own radius. |
--markdown-font-sans | ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif | Document font family. |
--markdown-font-mono | 'SFMono-Regular', Consolas, 'Liberation Mono', monospace | Code and math font family. |
These variables cover shared theme values. Use element classes for details such as highlight colors, code-toolbar
colors, or inline-code corners. Properties beginning with --_markdown- are internal resolved values.
Element reference
Every class below includes the full selector. Some elements only appear for the corresponding parser node type.
Document
The class prop is added to the root article. Scope overrides to that class when a page has several documents.
| Selector | Element |
|---|---|
.markdown-svelte | Root article for all renderers; also has [data-markdown-svelte]. |
.markdown-svelte-stream | Additional root class for MarkdownStream; also has [data-markdown-svelte-stream]. |
.document {
max-width: 72ch;
margin-inline: auto;
line-height: 1.8;
}Headings and paragraphs
Use the level modifier to change one heading level. Set overall text size and line height on the document.
| Selector | Element |
|---|---|
.markdown-svelte-heading | All headings, h1 through h6. |
.markdown-svelte-heading--1, .markdown-svelte-heading--2, .markdown-svelte-heading--3, .markdown-svelte-heading--4, .markdown-svelte-heading--5, .markdown-svelte-heading--6 | Individual heading levels. |
.markdown-svelte-paragraph | Paragraph (p). |
.markdown-svelte-inline | Inline group (span). |
.markdown-svelte-text | Text node wrapper (span). |
.markdown-svelte-hardbreak | Explicit line break (br). |
.document .markdown-svelte-heading--2 {
margin-top: 2.5em;
border-bottom: 0;
}
.document .markdown-svelte-paragraph {
margin-block: 1em;
}Inline formatting and links
Highlights and other inline details can be styled directly when the theme variables do not cover them.
| Selector | Element |
|---|---|
.markdown-svelte-strong | Bold text (strong). |
.markdown-svelte-emphasis | Emphasis (em). |
.markdown-svelte-strikethrough | Deleted text (del). |
.markdown-svelte-highlight | Highlighted text (mark). |
.markdown-svelte-insert | Inserted text (ins). |
.markdown-svelte-subscript | Subscript (sub). |
.markdown-svelte-superscript | Superscript (sup). |
.markdown-svelte-inline-code | Inline code (code). |
.markdown-svelte-link | Markdown link (a). |
.markdown-svelte-emoji | Emoji wrapper (span). |
.markdown-svelte-reference | Unresolved reference text (span). |
.document .markdown-svelte-link {
text-decoration-thickness: 0.1em;
text-underline-offset: 0.2em;
}
.document .markdown-svelte-link:focus-visible {
outline: 2px solid currentColor;
outline-offset: 3px;
}
.document .markdown-svelte-highlight {
background: #e5edcf;
color: #34451f;
}
.document .markdown-svelte-inline-code {
border: 0;
border-radius: 0;
}Lists and definitions
Task checkboxes are disabled display elements. Definition classes apply to definition-list nodes supplied by the parser.
| Selector | Element |
|---|---|
.markdown-svelte-list | Ordered and unordered lists. |
.markdown-svelte-list--ordered | Ordered list (ol). |
.markdown-svelte-list--unordered | Unordered list (ul). |
.markdown-svelte-list-item | List item (li). |
.markdown-svelte-list-item--task | Task-list item modifier. |
.markdown-svelte-task-content | Task item content wrapper (div). |
.markdown-svelte-checkbox | Disabled checkbox (input). |
.markdown-svelte-definition-list | Definition list (dl). |
.markdown-svelte-definition-term | Definition term (dt). |
.markdown-svelte-definition-description | Definition body (dd). |
.document .markdown-svelte-list--unordered {
list-style-type: square;
}
.document .markdown-svelte-list-item::marker {
color: #6d7461;
}
.document .markdown-svelte-checkbox {
accent-color: #6d7461;
}
.document .markdown-svelte-definition-description {
margin-inline-start: 1.5rem;
}Quotes, callouts, and rules
Admonitions expose their lowercase kind through data-kind, such as warning, caution, danger, or error. Generic containers have a separate title class.
| Selector | Element |
|---|---|
.markdown-svelte-blockquote | Blockquote. |
.markdown-svelte-thematic-break | Thematic break (hr). |
.markdown-svelte-admonition | Admonition wrapper (aside). |
.markdown-svelte-admonition-title | Admonition title (strong). |
.markdown-svelte-container | Generic fenced container (aside). |
.markdown-svelte-container-title | Container title (strong). |
.document .markdown-svelte-blockquote {
border-radius: 0;
background: transparent;
font-style: italic;
}
.document .markdown-svelte-admonition[data-kind='warning'] {
border-color: #986315;
background: #fff8e8;
}
.document .markdown-svelte-admonition[data-kind='warning'] .markdown-svelte-admonition-title {
color: #70460c;
}
.document .markdown-svelte-thematic-break {
margin-block: 2rem;
}Code blocks and diffs
Code is rendered as text; no syntax highlighter is bundled. Diff blocks show split panes when the node includes originalCode or updatedCode. The copy button exposes data-state="idle", "copied", or "failed".
| Selector | Element |
|---|---|
.markdown-svelte-code-block | Outer code block (div). |
.markdown-svelte-code-header | Language and copy toolbar (div). |
.markdown-svelte-code-language | Language label (span). |
.markdown-svelte-code-copy | Copy button (button). |
.markdown-svelte-code-pre | Code surface (pre); contains code. |
.markdown-svelte-diff | Split diff layout (div). |
.markdown-svelte-diff-pane | Diff pane (section). |
.markdown-svelte-diff-pane--original, .markdown-svelte-diff-pane--updated | Original and updated pane modifiers. |
.markdown-svelte-diff-label | Pane label (strong). |
.document .markdown-svelte-code-block {
border-radius: 0;
box-shadow: none;
}
.document .markdown-svelte-code-pre {
font-size: 0.9rem;
}
.document .markdown-svelte-code-copy[data-state='copied'] {
color: #bbf7d0;
}Tables
Keep horizontal scrolling on the wrapper for narrow screens. Column alignment comes from Markdown alignment markers and is applied as an inline text-align style on each cell.
| Selector | Element |
|---|---|
.markdown-svelte-table-wrapper | Scrollable table wrapper (div). |
.markdown-svelte-table | Table. |
.markdown-svelte-table-head | Header group (thead). |
.markdown-svelte-table-body | Body group (tbody). |
.markdown-svelte-table-row | Table row (tr). |
.markdown-svelte-table-cell | All header and body cells. |
.markdown-svelte-table-cell--header | Header cell (th). |
.markdown-svelte-table-cell--body | Body cell (td). |
.document .markdown-svelte-table-wrapper {
border: 0;
border-radius: 0;
}
.document .markdown-svelte-table-cell {
padding: 0.75rem 1rem;
}
.document .markdown-svelte-table-body .markdown-svelte-table-row:nth-child(even) {
background: #f3f4ee;
}Images
Images fit their container by default. The fallback span displays alt text when the source URL is missing or rejected by the URL policy.
| Selector | Element |
|---|---|
.markdown-svelte-image | Image (img). |
.markdown-svelte-image-fallback | Alt-text fallback (span). |
.document .markdown-svelte-image {
border: 0;
border-radius: 0;
margin-inline: 0;
}Math
Math is displayed as source text. Styling these elements does not typeset the expression; no math renderer is bundled.
| Selector | Element |
|---|---|
.markdown-svelte-math-inline | Inline math source (code). |
.markdown-svelte-math-block | Block math source (pre); contains code. |
.document .markdown-svelte-math-inline {
border: 0;
background: transparent;
}
.document .markdown-svelte-math-block {
border-radius: 0;
text-align: center;
}Footnotes
Style classes rather than generated IDs. idPrefix namespaces IDs when multiple rendered documents share a page.
| Selector | Element |
|---|---|
.markdown-svelte-footnote | Footnote definition wrapper (div). |
.markdown-svelte-footnote-label | Definition number (sup). |
.markdown-svelte-footnote-content | Definition content (div). |
.markdown-svelte-footnote-reference | Inline reference (sup). |
.markdown-svelte-footnote-reference-link | Link from a reference to its definition (a). |
.markdown-svelte-footnote-backlink | Return link to the reference (a). |
.document .markdown-svelte-footnote {
font-size: 0.85rem;
}
.document .markdown-svelte-footnote-reference-link {
text-decoration: none;
}HTML and fallbacks
Raw HTML is escaped by default. With allowRawHtml, sanitized HTML is rendered inside these wrappers. Its descendants do not receive Markdown classes; target their tags beneath your document class.
| Selector | Element |
|---|---|
.markdown-svelte-html-block | Sanitized HTML block wrapper (div). |
.markdown-svelte-html-inline | Sanitized inline HTML wrapper (span). |
.markdown-svelte-html-escaped | Escaped HTML source (span). |
.markdown-svelte-fallback | Raw source for an unsupported node (span). |
.document .markdown-svelte-html-block details {
padding-block: 0.75rem;
border-bottom: 1px solid #dce1d3;
}
.document .markdown-svelte-html-escaped {
font-family: ui-monospace, monospace;
}Streaming motion
Set these variables on your MarkdownStream class to adjust animation timing. Motion respects prefers-reduced-motion. For rendering without animation, use MarkdownRenderer from markdown-svelte with the same nodes array.
.document {
--markdown-stream-fade-duration: 200ms;
--markdown-stream-line-duration: 100ms;
--markdown-stream-size-duration: 160ms;
--markdown-stream-enter-duration: 140ms;
--markdown-stream-media-duration: 160ms;
} | Variable | Default | Applies to |
|---|---|---|
--markdown-stream-fade-duration | 280ms | Appended text and inline-code fades. |
--markdown-stream-fade-easing | cubic-bezier(0.33, 0, 0.67, 1) | Appended text fade easing. |
--markdown-stream-line-duration | 110ms | New block lines, list items, cells, and atomic inline nodes. |
--markdown-stream-line-easing | cubic-bezier(0.25, 0.46, 0.45, 0.94) | New line and item easing. |
--markdown-stream-size-duration | 180ms | Code- and math-block height transitions. |
--markdown-stream-size-easing | cubic-bezier(0.25, 0.46, 0.45, 0.94) | Height transition easing. |
--markdown-stream-enter-duration | 160ms | Container and thematic-break entrances. |
--markdown-stream-enter-easing | cubic-bezier(0.25, 0.46, 0.45, 0.94) | Container and thematic-break easing. |
--markdown-stream-media-duration | 180ms | Image reveal after loading. |
Additional streaming classes
The renderer adds these classes for animated content. Prefer timing variables for motion changes. Code and math heights are calculated by the renderer; overriding their height, vertical padding, or overflow can interfere with sizing during a stream.
| Selector | Element |
|---|---|
.markdown-svelte-stream-delta | Temporary span around newly appended text. |
.markdown-svelte-stream-list-item | Animated list item. |
.markdown-svelte-stream-definition-item | Wrapper around a definition term and body. |
.markdown-svelte-stream-footnote | Animated footnote definition. |
.markdown-svelte-stream-table-cell | Inner cell content wrapper. |
.markdown-svelte-stream-math-block | Animated block math. |
.markdown-svelte-stream-code-size, .markdown-svelte-stream-math-size | Elements with managed height transitions. |
.markdown-svelte-stream-block-enter | Blockquote, admonition, and container entrance. |
.markdown-svelte-stream-rule | Thematic-break entrance. |
.markdown-svelte-stream-code-language | Language label entrance. |
.markdown-svelte-stream-image, .markdown-svelte-stream-image--loaded | Image reveal and loaded state. |
See the streaming guide for worker parsing and frame-paced state updates.