Media
Placeholder image block
The default state of an infobox image — use this until you actually have a picture for the entry.
<div class="infobox-image" style="aspect-ratio: 16 / 9;">[ NO IMAGE AVAILABLE ]</div>Replacing the placeholder with a real image
On an Infobox, just set the entry's image frontmatter field — the component swaps the placeholder for a real <img> automatically, keeping the exact aspect-ratio and border. Outside the infobox (writing raw HTML directly) drop an <img> inside the same .infobox-image box instead, with padding: 0 so the image reaches the edges and object-fit: cover so it crops to fill the box neatly.
# in frontmatter:
image: "/images/the-lobby.jpg"
# or, writing the infobox HTML by hand:
<div class="infobox-image" style="aspect-ratio: 16 / 9; padding: 0;">
<img src="/images/the-lobby.jpg" alt="Describe what's in the image"
style="width: 100%; height: 100%; object-fit: cover; display: block;">
</div>Image embed (in the article body)
For a picture inside the Description or Notable Occurrences text, rather than the infobox, use.entry-image instead — it's a simple bordered block image with an optional caption line underneath.
Fig. 1 — Caption or source credit goes here.
<img class="entry-image" src="/images/photo.jpg" alt="Describe what's in the image">
<p class="entry-image-caption">Fig. 1 — Caption or source credit goes here.</p>Fullscreen lightbox (image & video)
Add the lightbox class to any <img> or <video> — it's a boolean, on or off, so leave it off anything you don't want clickable. Click the image below to see it fullscreen (Escape or click the background to close).
<img class="entry-image lightbox" src="/images/photo.jpg" alt="Describe what's in the image">
<!-- works the same way on a self-hosted <video> -->
<video class="entry-video lightbox" src="/videos/clip.mp4" controls></video>GIF
Just an <img> — browsers autoplay and loop GIFs natively, no extra markup needed. Use.entry-image the same as any other picture, and stack lightbox on it too if you want it to open fullscreen.
<img class="entry-image" src="/images/clip.gif" alt="Describe what's happening in the loop">Self-hosted video (not YouTube)
For a video file you're hosting yourself rather than embedding from YouTube, put it inpublic/videos/ and use a plain HTML5 <video> with .entry-video — it gets the same border and full-width sizing as .entry-image. Add more than one <source> if you're offering multiple formats.
<video class="entry-video" controls poster="/images/poster.jpg">
<source src="/videos/clip.mp4" type="video/mp4">
<source src="/videos/clip.webm" type="video/webm">
Your browser doesn't support embedded video.
</video>YouTube embed
Wrap the iframe in .video-embed so it stays a locked 16:9 rectangle and resizes with the page instead of overflowing it. Swap VIDEO_ID for the part of the YouTube URL afterwatch?v=. The youtube-nocookie.com domain is YouTube's own privacy-enhanced embed host — it skips setting tracking cookies until the viewer actually presses play.
<div class="video-embed">
<iframe src="https://www.youtube-nocookie.com/embed/VIDEO_ID"
title="YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen></iframe>
</div>Image comparison slider (before / after)
Use the CompareSlider component — hold the middle handle and drag left or right to reveal more or less of the "before" image (works with touch too). The handle is also keyboard-focusable — arrow keys nudge it, Home/End jump to either end. Needs exactly two images at a matching aspect ratio (16:9). Pass start=30 to change where it starts (defaults to 50%).
import CompareSlider from "../../components/CompareSlider.astro";
<CompareSlider before="/images/before.jpg" after="/images/after.jpg" />Audio embed
A plain HTML5 <audio> player with .entry-audio for full-width sizing. Browser controls can't be restyled beyond that without a custom JS player, which is out of scope here.
<audio class="entry-audio" controls src="/audio/recording.mp3"></audio>