CMS and Markdown

Renderer-neutral prose defaults for task lists, footnotes, definitions, figures, embeds, and resilient long-form composition.

CSS Tags styles semantic renderer output through .prose or [data-prose]. It does not require a Markdown runtime or replace native content elements.

Semantic article defaults

No renderer-specific classes are needed: the prose scope styles ordinary headings, paragraphs, and lists as a coherent article.

Building resilient content systems

Well-structured HTML gives a CMS useful typography before any custom blocks or application code are involved.

What the content model provides

Authors can express hierarchy and relationships with familiar native elements:

  • Headings create a navigable document outline.
  • Paragraphs inherit a readable measure and rhythm.
  • Lists support nested ideas without custom wrappers.

    • Ordered and unordered lists share the prose rhythm.
    • Long items wrap inside the article measure.

Start with the source

The same fragment remains useful in Markdown previews, CMS pages, feeds, and print styles.

Rendered CMS fragment

Markdown-style article output

This is ordinary semantic HTML using hooks emitted by common Markdown and CMS renderers.

Release checklist #

A renderer can compose tasks, definitions, quotations, tables, disclosure, and footnotes without component wrappers.

  • API reviewed
  • Migration guide published
Progressive enhancement
A complete baseline with optional platform upgrades.
Composition
Native content that remains useful in layouts and components.

Content should remain useful before the decoration arrives.

CSS Tags philosophy
Renderer support
OutputHook
Tasks.task-list-item
Footnotesdata-footnotes
Implementation note

Disclosure remains a native details element without JavaScript.

The renderer can emit a footnote.1

  1. The original source.

Prose scopes

<article data-prose>...</article>
<article data-prose="compact">...</article>
<article data-prose="wide">...</article>
<article class="prose prose-unbounded">...</article>

Default prose uses the body measure. Compact tightens rhythm, wide uses the wide measure, and unbounded delegates width entirely to the surrounding layout. Apply prose to the authored article body, not the application shell.

Renderer-neutral hooks

ContentPreferred output and accepted hooks
Tasks.contains-task-list / [data-task-list] and .task-list-item / [data-task-list-item]
Footnotes[data-footnotes] or .footnotes, with ref/backref data hooks
Heading linksDirect .heading-anchor__link or [data-heading-anchor] child
DefinitionsNative dl, dt, and dd
QuotesNative blockquote with optional direct footer or cite
FiguresNative figure and figcaption
TablesNative table and optional caption
DisclosureNative details and summary
MediaNative images, pictures, video, audio, SVG, and iframe embeds

The hooks are visual contracts only. Task state belongs in a checkbox, footnotes require IDs and links, and heading permalinks need accessible labels.

Overflow and composition

Long links and inline code wrap without widening the article. Fenced code and direct native tables retain independent horizontal scrolling. Media is bounded to the prose width, and fragment targets account for sticky headers.

Keep data-prose on the article column rather than a grid containing navigation. A wrapped table needs overflow on its wrapper or the richer data-table API.

Important tokens

  • --prose-task-gap, --prose-task-marker-offset
  • --prose-footnotes-gap, --prose-footnotes-border, --prose-footnotes-font-size
  • --prose-heading-scroll-margin, --prose-heading-anchor-gap
  • --prose-quote-cite-gap, --prose-definition-gap
  • --prose-table-scrollbar-gutter, --prose-embed-min-height
  • --prose-link-wrap, --prose-inline-code-wrap

Integration checklist

  1. Preserve semantic heading, list, table, quote, figure, and disclosure HTML.
  2. Sanitize user-authored HTML.
  3. Generate unique heading and footnote IDs across repeated fragments.
  4. Provide media alternatives, captions, or transcripts.
  5. Test long URLs, missing media, nested lists, 200% text, RTL, dark mode, and narrow containers.