Encrypt Reveal Card — Free HTML CSS JS Cipher Hover Snippet
Encrypt Reveal Card · Cards · Plain HTML, CSS & JS · Live preview
What's included
Features
About this UI Snippet
Encrypt Reveal Card — Cipher Characters Unmasked by the Cursor

The encrypt-reveal card is the security-themed effect popularized by Evervault's site: a card shows a locked icon at rest, but as you move your cursor over it, a field of constantly-churning encrypted characters becomes visible only inside a circular window that follows the pointer — as if you're decrypting the surface in real time. This snippet recreates it with plain HTML, CSS masks, and a small vanilla JavaScript generator.
A masked window that follows the cursor
The character stream fills the whole card but is revealed through a mask-image radial gradient centered on two CSS custom properties, --mx and --my. A pointermove handler writes the cursor's position into those variables, so the opaque part of the mask — a 140px circle — tracks under the pointer while everything outside it is masked to transparent. The effect is a moving porthole that exposes the "ciphertext" only where you point, which is the core illusion. Updating the reveal through CSS variables keeps the handler extremely cheap.
Churning ciphertext
The text is a random 900-character string drawn from a hex-and-symbol alphabet (ABCDEF0123456789...!@#$%) that looks like encrypted data. To make it feel alive rather than static, the handler regenerates the string on roughly a quarter of pointer moves (Math.random() < 0.25). That throttle is deliberate: regenerating on every move would be wasteful and visually too frantic, while occasional regeneration reads as data actively scrambling under your cursor. Because only the masked region is visible, you mostly perceive the churn happening right where you look.
A glow that reinforces the reveal
A second layer, .ev-mask, is a soft radial purple glow also centered on --mx/--my. It fades in on hover and sits over the card to make the revealed region feel lit, like a scanner passing over the surface. Pairing a glow with the character mask gives the reveal depth instead of looking like a flat cut-out.
The resting state
At rest the card shows a centered lock icon and an "Encrypted" label, and the character stream is at opacity: 0. On hover the stream fades to full opacity (within its mask) while the lock label dims to opacity: .15, so the card transitions from "secured" to "decrypting" as you interact. This clear before/after state communicates the metaphor without any copy.
Why masks instead of clip
Using mask-image rather than clip-path lets the reveal have a soft, feathered edge — the radial gradient fades from opaque to transparent over its radius, so the porthole blends smoothly into the hidden area rather than showing a hard circular cut. That softness is what makes it feel like a scanning beam.
Customizing it
Change the mask circle radius to widen or tighten the reveal, edit the CHARS alphabet (Katakana for a Matrix look, or 0/1 for binary), recolor the stream and glow, or adjust the 0.25 regeneration probability for calmer or busier churn. Swap the lock icon for your brand. Pair it with a glow input on a security product page or a background boxes hero.
Build with AI
Build, Understand, Optimize, and Extend It With AI
You don't have to guess why this reveal feels like a scanning beam instead of a hard cutout. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly how the mask-image radial gradient centered on the --mx and --my custom properties produces the feathered porthole effect, and why that specific approach was chosen over clip-path. The same assistant can help optimize it — ask whether regenerating a 900-character string on 25 percent of pointer moves is the right throttle for slower devices, or whether the random-string generation could be precomputed into a pool of strings swapped instead of built from scratch each time. It's also useful for extending the effect: ask it to make the mask radius pulse subtly on its own when the cursor is idle, add a second card variant themed around decrypting an image instead of text, or trigger a brief "decrypted" success state after a few seconds of hovering. 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 cursor-revealed "encrypted card" effect in plain HTML, CSS, and JavaScript using CSS mask-image and custom properties — no canvas, no library.
Requirements:
- A card containing a full-size layer of dense, randomly generated hex-and-symbol characters that is hidden by default, plus a centered resting state showing a lock icon and label.
- Use a CSS mask-image (and its -webkit- prefixed equivalent) with a radial-gradient value centered on two CSS custom properties representing the cursor's x and y position relative to the card, so only a circular region around the cursor reveals the character layer while the rest stays masked to transparent.
- The radial gradient must have a soft, feathered falloff (opaque at the center fading to transparent by its edge) rather than a hard-edged circle, so the reveal reads as a glowing scanner rather than a stencil cutout.
- On pointermove over the card, update only the two CSS custom properties via style.setProperty — never touch layout-affecting properties — so the reveal tracking stays cheap every frame.
- Regenerate the random character string only some of the time (not on every single pointermove event), so the "ciphertext" visibly churns without wastefully re-rendering on every pixel of mouse movement.
- Add a second, larger radial-gradient glow layer also centered on the same cursor coordinates, positioned above the character layer, that fades in on hover to make the revealed area feel lit rather than flat.
- Fade the resting lock icon and label to a low opacity on hover so the card visually shifts from a "secured" state to a "decrypting" state as the user interacts with it.
- Use a monospace font for the character stream to sell the encrypted-data look.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 card shows a lock icon labeled Encrypted at rest.
- 2Move the cursor over itA circular window reveals churning encrypted characters.
- 3Move aroundThe reveal window follows the pointer like a scanner.
- 4Watch it churnThe ciphertext scrambles as you move.
- 5Change the alphabetEdit CHARS for binary, hex, or Katakana.
- 6Resize the windowAdjust the mask circle radius and glow.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
The character stream fills the card but is shown through a mask-image radial gradient centered on the --mx and --my CSS variables. A pointermove handler writes the cursor position into those variables, so the opaque 140px circle of the mask tracks under the pointer while everything outside is masked to transparent — a moving porthole over the ciphertext.
The 900-character random string is regenerated on roughly a quarter of pointer moves (Math.random() < 0.25). Throttling it that way keeps the work cheap and the churn from looking too frantic, while still reading as data actively scrambling. Since only the masked region is visible, you perceive the churn right where you point.
mask-image with a radial gradient gives a soft, feathered edge — it fades from opaque to transparent across its radius, so the revealed area blends smoothly into the hidden surface. clip-path would produce a hard circular cut. The feathering is what makes the porthole feel like a scanning beam rather than a stencil.
No. The reveal moves purely by updating two CSS variables, which is very cheap, and the text only regenerates on about 25% of moves. There's no per-frame loop and no layout thrashing — the mask and glow are GPU-composited, so it stays smooth even on modest devices.
Keep the ciphertext in a ref and a pointermove handler that updates the --mx/--my inline style and occasionally regenerates the string. Avoid putting the churning text in state, since that would re-render constantly — write it directly to a ref'd element. The mask CSS ports as-is; in Tailwind use arbitrary mask-image values with the inline variables.