Meteor Card — Free HTML CSS JS Shooting Star Snippet
Meteor Card · Cards · Plain HTML, CSS & JS · Live preview
What's included
Features
About this UI Snippet
Meteor Card — Shooting Stars Streaking Across a Card

The meteor card is the atmospheric effect where thin shooting stars streak diagonally across a dark card, each with a glowing trailing tail — turning a plain pricing or feature card into a tiny night sky. This snippet builds it with plain HTML, CSS, and a small vanilla JavaScript generator, with randomized timing so the shower looks natural and an IntersectionObserver to pause it when off-screen.
A meteor is a dot with a tail
Each meteor is a tiny 2px dot, and its glowing trail is a ::before pseudo-element: a 60px-wide horizontal gradient that fades from light indigo to transparent, attached to the dot's trailing side. The whole thing is rotated -45° so it travels and points diagonally. This two-part construction — a head plus a gradient tail — is what reads as a shooting star rather than a moving dot, and it's pure CSS with no images.
The falling animation
The mcFall keyframe translates each meteor from the top toward the bottom-left by translate(-340px, 340px) while keeping the -45° rotation, and fades it out near the end of its travel. Because the card has overflow: hidden, meteors are clipped to the card's rounded bounds, so they appear and disappear at the edges like real streaks crossing a window. The animation is linear infinite, so each meteor loops forever.
Randomization is the whole trick
If every meteor shared the same start position, delay, and speed, you'd see an obvious grid of synchronized lines. The JavaScript generates 14 meteors, each with a random horizontal start (some beginning beyond the right edge), a random animation-delay up to 6 seconds, and a random animation-duration between 3 and 7 seconds. Those three randomized values mean meteors enter at different times, places, and speeds, so the shower looks scattered and organic — the single most important detail for selling the effect.
Pausing off-screen
A continuously animating shower wastes CPU and battery when nobody's looking at it, so an IntersectionObserver watches the card and toggles each meteor's animationPlayState between running and paused as the card enters and leaves the viewport. With threshold: 0 it switches the moment any part of the card is visible. This is a lightweight, scroll-listener-free way to keep decorative animations efficient.
Layering over content
The meteors live in an absolutely positioned layer behind the card body (which sits at a higher z-index), so the streaks pass behind the icon, heading, and button without obscuring them. The card's radial-gradient background and indigo glow shadow complete the cosmic look, and the content remains fully readable.
Customizing it
Change COUNT for a denser or sparser shower, widen the random duration range for more speed variety, lengthen the tail by editing the ::before width, or recolor the trail gradient to match your theme. Adjust the travel distance in mcFall if you resize the card. Pair it with a pin card or a focus cards grid for a striking set of cards, or use it as a premium pricing card tier.
Build with AI
Build, Understand, Optimize, and Extend It With AI
You don't need to eyeball the timing math to know why this shower looks natural. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly how the randomized left position, animation-delay, and animation-duration together prevent the meteors from ever looking like a synchronized grid, or why the mcFall keyframe's translate distance has to match the card's actual dimensions to keep streaks clipped cleanly at the rounded corners. The same assistant is useful for optimizing it — asking whether animating transform and opacity only (rather than any layout-affecting property) is what keeps 14 looping meteors cheap, or whether the IntersectionObserver threshold should change for a card that scrolls partially into view. It's also a quick way to extend the effect: ask it to vary meteor color by size for a parallax feel, add an occasional larger "bright" meteor, or drive the COUNT constant responsively so denser showers only render on larger cards. Treat the code less like a finished artifact and more like a starting point for a conversation.
Prompt to recreate it
Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:
Build a "meteor shower card" in plain HTML, CSS, and a small vanilla JavaScript generator using only CSS keyframe animations and an IntersectionObserver — no canvas, no libraries.
Requirements:
- A card with overflow: hidden and a dark radial-gradient background, containing an absolutely positioned layer for the meteors that sits behind the card's actual content (icon, heading, paragraph, button), which must stay on top via z-index.
- Each meteor is a single small element: a tiny circular "head" plus a glowing tail built from a ::before pseudo-element that is a horizontal linear-gradient fading from a light color to transparent, with the whole element rotated -45 degrees so the head-and-tail reads as a diagonal shooting star.
- Define one CSS @keyframes rule that translates a meteor from its start position diagonally down-and-left by a fixed pixel distance while keeping the same rotation, and fades its opacity to 0 near the end of the travel, running linear and infinite.
- In JavaScript, generate a fixed number of meteor elements (a constant, e.g. 14) and for each one set three independently randomized inline values: a random horizontal starting position (allow some to start beyond the right edge of the card), a random animation-delay (e.g. 0 to 6 seconds), and a random animation-duration (e.g. 3 to 7 seconds) — the randomization across all three is what must prevent the shower from ever looking like a synchronized grid of identical streaks.
- Add an IntersectionObserver (threshold 0) watching the card element that sets every meteor's animationPlayState to "running" when the card is intersecting the viewport and "paused" when it is not, so the shower stops consuming animation frames while off-screen.
- Do not use JavaScript to move the meteors frame by frame — all motion must come from the CSS animation; JavaScript only creates the elements, randomizes their timing, and toggles play state.Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.
Step by step
How to Use
- 1Paste HTML, CSS, and JSA dark card renders with meteors streaking diagonally across it.
- 2Watch the showerThin shooting stars cross the card at scattered times and speeds.
- 3Note the clippingMeteors appear and vanish at the card's rounded edges.
- 4Scroll it off-screenThe shower pauses automatically to save cycles.
- 5Change the densityEdit COUNT for more or fewer meteors.
- 6Recolor the trailsAdjust the tail gradient and length to your theme.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
Each meteor is a tiny 2px dot with a ::before pseudo-element that is a 60px horizontal gradient fading to transparent — the glowing tail. The whole element is rotated -45 degrees so it travels and points diagonally. The head-plus-tail construction is what makes it read as a shooting star, and it's entirely CSS with no image assets.
The JavaScript gives each of the 14 meteors a random horizontal start, a random animation-delay up to 6 seconds, and a random duration between 3 and 7 seconds. Because they enter at different times, positions, and speeds, the shower looks scattered and organic rather than a grid of identical lines firing together.
An IntersectionObserver with threshold 0 watches the card and toggles each meteor's animationPlayState between running and paused as the card enters or leaves the viewport. That stops the continuous animation work whenever the card isn't visible, without needing a scroll listener.
The meteors live in an absolutely positioned layer, and the card body sits above them at a higher z-index. So the streaks pass behind the icon, heading, and button. The card's overflow: hidden also clips them to its rounded bounds so they enter and exit cleanly at the edges.
Generate the meteor elements from an array in render, applying the random left, delay, and duration as inline styles computed once. Keep the IntersectionObserver in a mount effect with cleanup on unmount, using a ref to the card. The CSS keyframe and tail port directly; in Tailwind, define mcFall in the config and render the meteors with arbitrary inline animation styles.