webdevpuneet.com

Dot Reveal Card — Free HTML CSS JS Canvas Hover Snippet

Dot Reveal Card · Scroll · Plain HTML, CSS & JS · Live preview

Copy & paste

Source Code

<div class="cr-grid" id="crGrid">
  <article class="cr-card" style="--c1:#6366f1;--c2:#22d3ee">
    <canvas class="cr-canvas"></canvas>
    <div class="cr-face"><span class="cr-icon">⚡</span></div>
    <div class="cr-hover"><h3>Fast</h3><p>Edge-deployed, sub-50ms responses worldwide.</p></div>
  </article>
  <article class="cr-card" style="--c1:#ec4899;--c2:#f59e0b">
    <canvas class="cr-canvas"></canvas>
    <div class="cr-face"><span class="cr-icon">🛡</span></div>
    <div class="cr-hover"><h3>Secure</h3><p>End-to-end encryption with zero-knowledge storage.</p></div>
  </article>
  <article class="cr-card" style="--c1:#34d399;--c2:#10b981">
    <canvas class="cr-canvas"></canvas>
    <div class="cr-face"><span class="cr-icon">∞</span></div>
    <div class="cr-hover"><h3>Scalable</h3><p>Autoscale from zero to millions without a config.</p></div>
  </article>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Per-card canvas
Each card draws its own HiDPI dot grid.
Data-driven dots
Position, color, and timing stored per dot.
Staggered reveal
Random per-dot delays assemble the matrix.
On-demand loop
rAF runs only while hovering, idle cards do nothing.
Theme via variables
--c1/--c2 color each card's dots.
Layered transitions
Canvas, icon, and content cross-fade.
HiDPI crisp
devicePixelRatio scaling keeps dots sharp.
Responsive grid
Three columns collapse to one on mobile.

About this UI Snippet

Dot Reveal Card — Staggered Canvas Dot Matrix on Hover

Screenshot of the Dot Reveal Card snippet rendered live

The dot-reveal card is the feature-grid interaction where hovering a card paints a matrix of tiny colored dots across it — each dot fading in on its own slight delay so the pattern materializes organically — while the resting icon dissolves into a heading and description. This snippet builds it with plain HTML, CSS, and a per-card HTML <canvas> driven by vanilla JavaScript.

A dot grid on canvas

Each card has its own <canvas> sized to the card with devicePixelRatio scaling (capped at 2) so the dots stay crisp on retina screens. On build, a double loop walks the canvas every gap pixels and creates a dot record at each position, assigning it one of the card's two theme colors (read from the --c1/--c2 CSS variables) at random. Storing dots as data — position, color, and timing — lets the animation be a simple replay over that array.

Staggered, organic fill-in

If every dot appeared at once, the reveal would look like a flat overlay flicking on. Instead, each dot gets a random delay up to 600ms. When you hover, all dots record the same start time t0, and each dot's fade progress is (now - t0 - delay) / 400 clamped to 0–1. Because the delays are random, dots wink on in a scattered order over roughly a second, so the matrix appears to assemble itself — the detail that makes it feel alive rather than mechanical.

The animation loop, started on demand

The requestAnimationFrame loop only runs while you're hovering. On pointerenter it stamps every dot's start time and kicks off the loop; on pointerleave it cancels the frame and clears the canvas. Running the loop on demand — not continuously for every card on the page — keeps a grid of these cards cheap, since idle cards do zero work.

Layered content transitions

Three stacked layers compose the card: the canvas at the back (fading in via CSS opacity on hover), the resting icon face in the middle (fading out), and the hover content on top (sliding up and in). The canvas opacity transition and the dot animation overlap, so the dots both fade in as a layer and individually stagger — a subtle double reveal. The heading and copy rise into place once the icon clears.

Why a canvas here

Hundreds of dots as DOM elements would be heavy and awkward to animate individually. A single canvas per card draws them all in one paint per frame, with per-dot alpha controlled in code, which is far more efficient and gives precise control over the stagger timing that CSS alone couldn't easily express.

Customizing it

Change gap for a denser or sparser matrix, adjust the 600ms delay spread and 400ms fade for a faster or slower assembly, set each card's --c1/--c2 to theme its dots, or change the dot size in fillRect. The grid collapses to a single column on narrow screens. Pair it with a glare card or a wobble card for a varied feature section.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSThree feature cards render, each showing an icon at rest.
  2. 2
    Hover a cardA matrix of colored dots fades in across the canvas.
  3. 3
    Watch the staggerDots wink on in a scattered order, assembling the pattern.
  4. 4
    See the contentThe icon dissolves and a heading and copy rise in.
  5. 5
    Theme the dotsSet each card's --c1 and --c2 colors.
  6. 6
    Tune the matrixAdjust the gap, delay spread, and fade duration.

Real-world uses

Common Use Cases

Dot-matrix feature grids
Offer a richer alternative to plain feature cards, painting a staggered dot matrix across a card on hover.
Product benefit highlights
Pair with a feature tabs showcase, with the resting icon fading out to reveal text as dots appear.
Developer tool sites
Match an animated grid background hero on a developer tool site, with each card drawing its own HiDPI dot grid.
Pricing perk highlights
Reveal perks beside a pricing card, with the animation loop running only while a card is hovered.
Canvas effect reference
Study a data-driven dot matrix where position, colour and timing are stored per dot, with random delays making the pattern assemble organically.
Related: Box Reveal
See the Box Reveal for a related scroll pattern worth pairing with this one.
Related: Hue-Rotating Scroll Background
See the Hue-Rotating Scroll Background for a related scroll pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

Each dot is assigned a random delay up to 600ms. On hover, every dot records the same start time, and its fade progress is (now - start - delay) / 400 clamped to 0–1. Because the delays differ, dots wink on in a scattered order over about a second, so the matrix appears to assemble itself rather than flicking on as a flat layer.

A dense dot matrix would be hundreds of DOM nodes, which is heavy to create and animate individually. One canvas per card draws every dot in a single paint per frame, with per-dot alpha controlled in code. That's far more efficient and gives precise control over the stagger timing that CSS alone couldn't easily express.

No. The requestAnimationFrame loop starts on pointerenter and is cancelled on pointerleave, which also clears the canvas. Idle cards do zero work, so a whole grid of these cards stays cheap — only the card you're actively hovering animates.

Each card sets two CSS custom properties, --c1 and --c2. The script reads them with getComputedStyle and assigns each dot one of the two colors at random, so a card's dot matrix matches its theme. Change those variables per card to recolor the reveal without touching the JavaScript.

Render the cards and use a ref to each canvas. In a mount effect per card, build the dot array and wire pointerenter/pointerleave to start and stop the rAF loop, cancelling on unmount. Keep dots and the frame id in refs, not state. The CSS layer transitions port directly; in Tailwind, position the canvas absolute inset-0 behind the content layers.