Animated newsletter header MP4s (that fall back to a still)
Build an animated newsletter header in HTML, render it to a deterministic MP4, and ship a still PNG as the fallback for clients that strip video.
An animated newsletter header is a six-to-eight-second loop at the top of your issue that plays in clients that allow inline video and falls back to a still PNG everywhere else. Built right, it ships from a single HTML file: the MP4 is the rendered sequence, the PNG is the last frame, and the layout doesn't drift between them.
This post is about the version that doesn't look like a 2014 GIF banner — a masthead title that slides in, an underline that draws across, and a stylized envelope icon that flips open on the beat.
The brief, in one paragraph
A newsletter header is not a hero image. It is the first three centimeters of a long-form artifact, and the reader's eye lands on it for under a second before deciding whether to scroll. The animation has one job: telegraph the issue's identity before the viewer makes that decision. Anything longer than a six-second loop is wasted; anything that requires audio is wrong; anything that distracts from the title is malpractice.
So: title in first, underline next, the envelope as a closing punctuation. The seal hitting the envelope is the cut.
Why hf-seek and not CSS keyframes
A CSS @keyframes animation runs at whatever rate the browser feels like. In a deterministic renderer, that produces drift — the first frame of your MP4 might be 0% or 4% of the animation depending on when capture started. The render engine emits an hf-seek event with e.detail.time (seconds) for every captured frame, and the animation reads the time from that event. Two renders of the same HTML produce byte-identical MP4s. See the deterministic rendering primer for the full reasoning.
addEventListener('hf-seek', (e) => {
const t = e.detail.time;
const titleP = Math.min(1, Math.max(0, (t - 0.4) / 1.1));
const ease = 1 - Math.pow(1 - titleP, 3);
title.style.clipPath = `inset(0 ${(1 - ease) * 100}% 0 0)`;
});The pattern is the same for every element on the page: clamp t into a per-element window, ease it, apply the transform. Composable, debuggable, and impossible to make non-deterministic.
The title slide
The masthead title uses clip-path: inset(0 100% 0 0) and animates the right inset from 100% to 0%. That gives you a left-to-right reveal that respects the typography — the letters aren't squished, they aren't slid in from offscreen, the descenders aren't clipped. The reveal duration is 1.1 seconds with a cubic ease-out, which is just slow enough to feel intentional and just fast enough not to feel pretentious.
A classic mistake is to fade the title in. Fades work for body copy. Titles want a gesture — a reveal, a wipe, a clip — because the gesture itself communicates "this is a publication, not a blog post."
The underline draw
The signal-red underline is the brand mark. It draws from 0 to 100% width over 0.8 seconds with an ease-in-out, which gives it a slight acceleration in the middle and a soft landing on the right edge. This is the same easing curve discussed in easing that looks like money — easeInOut(p) = p < 0.5 ? 2*p*p : 1 - ((-2*p + 2)^2)/2.
The envelope
The envelope is two layers: a black body and a green flap that rotates from rotateX(0deg) to rotateX(-170deg) to flip open. The seal — a small red dot — pops into place on the final beat with a slight overshoot. The whole envelope is 170×120 pixels because in the rendered MP4 it sits to the right of the title and reads as an icon, not an illustration. An icon at this scale should be readable in one glance.
The typography settings that matter
Three CSS declarations carry the header:
.title {
font-family: ui-serif, Georgia, serif;
font-size: 64px;
letter-spacing: -0.02em;
font-weight: 500;
}The serif communicates "publication." The -0.02em tracking tightens the optical spacing at large sizes — without it, the title looks like a Word document. The 500 weight is medium-bold; 700 is too heavy for a masthead, 400 is too light to read against a textured background.
Render to MP4
From the project root, with the HTML saved as header.html:
hyperframes render input.html --out clip.mp4 --duration 6 --fps 30That produces a 6-second MP4 at 30fps. For the still PNG fallback, render a single frame at t = duration:
hyperframes render input.html --out header.png --duration 6 --fps 30 --still --at 6The PNG is the canonical final state. The MP4 is the animated path to it. They never disagree.
<!-- Inline in your newsletter template -->
<a href="https://example.com/issue-42">
<video
src="https://cdn.example.com/issues/042/header.mp4"
poster="https://cdn.example.com/issues/042/header.png"
autoplay loop muted playsinline
width="600" height="200"
style="display:block;width:100%;max-width:600px">
<img src="https://cdn.example.com/issues/042/header.png" width="600" height="200" alt="The Deterministic Dispatch, Issue 042" />
</video>
</a>Templating across a year of issues
Once the template is solid, every issue is a row in a manifest. Title, kicker, accent color, optional second line. The renderer iterates the manifest and emits an MP4 + PNG pair per row. A year of weekly issues is 52 renders, finishes in under ten minutes on a single machine, and the diff between two issues is one line of CSV. The data-driven render recipe covers the full pipeline.
What not to do
A header isn't a place for confetti, sparkles, or a logo animation. The reader is on the cusp of scrolling past — the animation needs to resolve into the layout, not perform. If the loop ends on motion, the eye stays on the header and never reads the article. If it ends on a still, the eye moves down to the body copy. That's the rule.
A second mistake: don't loop the animation visibly. A 6-second loop should play once. Email clients will loop <video autoplay loop> on their own, but the second play-through should be optional — the viewer who scrolled in mid-loop sees the resolve, not the start.
For more on the editorial use of motion see kinetic typography for headlines and the broader case in HTML is the next video codec.
FAQ
Will the MP4 autoplay in Gmail?
No. Gmail web and the Gmail mobile apps both strip <video> and render only the poster PNG. Apple Mail, Outlook for iOS, and most third-party clients (Hey, Spark, Mimestream) play the MP4 inline. Design the still so the email looks finished without the motion.
What dimensions should the header be?
600 pixels wide is the safe email column width. Aspect ratio 3:1 (600×200) is the conservative choice; 2:1 (600×300) is more cinematic but pushes the body copy lower on small screens. Render at 2× (1200×400 or 1200×600) and let the email client downscale.
How big is the MP4?
A 6-second 30fps 1200×400 H.264 MP4 of this design is typically 200–400 KB. That's well inside email-friendly territory if you self-host. CDN-host it; never base64 a video into the email body.
Can the animation differ per recipient?
Yes — render per-recipient by templating the title or kicker. The deterministic pipeline means a name in the kicker line ("Hi, Marcus") produces a stable filename and a stable byte sequence. See batch personalized videos from CSV.
Does the still PNG have to be the last frame?
It doesn't have to be, but it should be. If the still is a mid-animation frame, the email looks broken — half-drawn underline, half-flipped envelope. The last frame is the resolved layout. Use it.
Close
A newsletter header is the first three centimeters of an issue and the only piece of motion the reader will tolerate. Build it once in HTML, render the MP4 and the PNG from the same source, and ship both. Twelve months from now you'll have a year of consistent headers, and the only thing that changed between them is a single line of data.
Start with the quickstart or open the playground and adapt the template above.
Cite this postBibTeX · APA · Markdown
@misc{okafor2026animated,
author = {Marcus Okafor},
title = {Animated newsletter header MP4s (that fall back to a still)},
year = {2026},
url = {https://hyperframes.video/blog/animated-newsletter-header},
note = {HyperFrames blog}
}Marcus Okafor. (2026, May 21). Animated newsletter header MP4s (that fall back to a still). HyperFrames. https://hyperframes.video/blog/animated-newsletter-header
[Animated newsletter header MP4s (that fall back to a still)](https://hyperframes.video/blog/animated-newsletter-header) — Marcus Okafor, 2026
Marcus leads design and motion at HyperFrames. Before that he shipped editorial motion for newsrooms and product launches. He thinks every easing curve has a personality.
Animated app onboarding screens to MP4
Build an animated app onboarding video in HTML — three-screen carousel with sliding screens, fading headlines, scaling illustrations, advancing dots — and render to MP4.
Animated meme generator (deterministic, scriptable)
Build a scriptable meme video generator in HTML — top-text bottom-text reveal, punchline punch-scale, shaky-cam emphasis — and render reproducible MP4s from a CSV.
Animated pull-quote cards for editorial video
Build an animated pull quote in HTML — oversized opening glyph, word-by-word typewriter, attribution rise — and render deterministic MP4s for editorial video pipelines.
Building with HyperFrames? Come hang out.
We're on GitHub, in Discord, and the playground is one click away. Bring weird ideas — we collect them.