A Tour of the Media Elements

L. Ipsum

December 3, 2025

Categorized as VitePress and Static Sites

Prose carries most of a post, but every so often you need something else on the page: a picture, a clip, someone else's words, a block of code. Here's what each of those looks like in LTheme.

An image, with a caption

Wrap it in <figure>/<figcaption> rather than a bare ![]() — the caption gets its own styling and spacing that a plain alt text never would.

Placeholder avatar used across this site
Any image works here — this one's just the site's own avatar, reused as a stand-in.

Add class="fullwidth" to the <figure> when an image should break out of the text column instead of sitting inside it.

A video

Video markup uses .video-wrapper around a native <video> tag — no player library required:

html
<div class="video-wrapper">
  <video src="/videos/demo.mp4" controls></video>
</div>

For a vertical/portrait clip, use .video-wrapper--portrait instead, which constrains the width and locks a 9:16 aspect ratio. Embedding YouTube or another external player works the same way, swapped to .iframe-wrapper around an <iframe>.

A quote

The best way to predict the future is to invent it.

Alan Kay

A blockquote with a <footer><cite>...</cite></footer> picks up the theme's right-aligned attribution styling automatically — no extra classes needed.

Some code

ts
export function tufteSidenotePlugin(md: MarkdownIt): void {
  md.inline.ruler.after("emphasis", "tufte-sidenote", (state, silent) => {
    // ^[...] becomes a margin note on desktop, tap-to-expand on mobile
  });
}

Fenced code blocks are highlighted with the one-dark-pro theme in both light and dark mode — that's a deliberate choice, not an oversightMost themes swap the code theme with the page theme. LTheme keeps one dark code theme everywhere so syntax highlighting never has to be retuned twice..