You Might Also Like
Flickering Grid — Free HTML CSS JS Canvas Texture Snippet
Flickering Grid · Animations · Plain HTML, CSS & JS · Live preview
What's included
Features
About this UI Snippet
Flickering Grid — Randomly Flickering Squares on Canvas

The flickering grid is the subtle, techy backdrop where a lattice of small squares flickers to random opacities — never the same twice, always quietly alive. It is a favorite ambient texture for AI, data, and developer sites. This snippet renders it on an HTML <canvas> with plain vanilla JavaScript, sharp on retina and efficient even with hundreds of cells.
A grid stored as a typed array
The grid is computed from cell SIZE and GAP: the canvas is divided into as many columns and rows as fit, and each cell's current brightness is stored in a Float32Array indexed by row * cols + col. A typed array is used deliberately — it holds the brightness of every cell in a compact, fast-to-iterate buffer, which matters because the draw loop touches every cell each frame. The array is seeded with random starting opacities so the grid is varied from the first frame.
The flicker logic
Each frame, a small fraction of cells (governed by FLICKER) are chosen at random to jump to a new random brightness, while the rest hold their current value. Redrawing every cell at its stored opacity then produces the flicker: most cells stay put on any given frame while a scattered few change, so the texture shimmers gently rather than strobing. Capping brightness at MAXA (0.55) keeps it subtle — a backdrop, not a distraction.
Drawing efficiently
The loop clears the canvas and fills each cell as a small fillRect at its opacity, skipping cells dimmer than a threshold so near-invisible squares cost nothing. Drawing solid rects (rather than per-cell gradients or shadows) keeps each frame cheap, which is what lets a few hundred cells animate at 60fps. The whole grid is one canvas, so it is a single element regardless of cell count.
Crisp on retina
Like any canvas, it scales with devicePixelRatio (capped at 2): the backing buffer is sized up and a setTransform lets drawing happen in CSS pixels while rendering at device resolution, so the square edges stay sharp on HiDPI screens. The grid rebuilds on resize to fit the new dimensions and recomputes the cell count.
Framing the content
A radial .fg-fade vignette darkens the grid toward the edges so the flicker emerges from darkness and the lattice does not end abruptly, keeping focus on the centered headline. The content sits above the canvas at a higher z-index with a soft text-shadow for legibility.
Customizing it
Change SIZE and GAP for a finer or chunkier grid, FLICKER for a busier or calmer shimmer, MAXA for brighter or subtler squares, and COLOR for any hue. Lower the DPR cap or raise the skip threshold for very low-end targets. Pair it with a dot pattern or particle network for a layered technical hero, or an aurora text headline on top.
Build with AI
Build, Understand, Optimize, and Extend It With AI
You don't need to work out the Float32Array indexing or the DPR math by hand. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly why cells are stored in a Float32Array indexed by row times cols plus col rather than an array of objects, and why the devicePixelRatio scaling combined with ctx.setTransform is what keeps the squares sharp on retina screens. The same assistant can help optimize it — ask whether the FLICKER probability check inside the nested row/col loop could be restructured to touch fewer cells per frame at very large grid sizes, or whether the skip-if-dim threshold should scale with cell count. It's also useful for extending the effect: have it add a mouse-proximity brightness boost, a second color layer for a duotone flicker, or a version that reacts to audio input. 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 "flickering grid" ambient background texture in plain HTML, CSS, and JavaScript using only the Canvas 2D API and requestAnimationFrame — no libraries.
Requirements:
- A canvas positioned absolutely to fill its parent section, resized in JS from canvas.clientWidth/clientHeight (not just CSS), and scaled for devicePixelRatio (capped at 2) using ctx.setTransform so drawing coordinates stay in CSS pixels while the backing buffer renders at full device resolution.
- Compute how many grid columns and rows fit the canvas from a configurable cell size and gap, and store every cell's current brightness (an alpha value) in a single Float32Array indexed by row times column-count plus column — not an array of per-cell objects.
- Seed every cell with a random starting brightness capped at a maximum alpha (well under 1, so the effect stays subtle) when the grid is built or rebuilt.
- On every animation frame, clear the canvas, then for each cell: with a small per-frame probability, reassign that cell a new random brightness (also capped at the maximum); then, if the cell's current brightness is above a small visibility threshold, fill a small square at its grid position using that brightness as the fillStyle alpha, skipping the fillRect entirely for near-invisible cells.
- Rebuild the entire grid (recompute columns, rows, and the typed array) on window resize.
- Layer a radial-gradient vignette div over the canvas so the flicker fades to the background color at the edges, with page content sitting above both in a centered, higher z-index layer.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 grid of squares flickers softly behind the headline.
- 2Watch the shimmerScattered cells change brightness each moment.
- 3Note the vignetteThe grid fades into the page toward the edges.
- 4Resize the windowThe grid rebuilds and stays crisp on retina.
- 5Tune the flickerAdjust FLICKER, MAXA, SIZE, and GAP.
- 6Recolor itChange the COLOR RGB string.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
A Float32Array holds the brightness of every cell in a compact, fast-to-iterate buffer indexed by row times columns plus column. The draw loop touches every cell each frame, so a typed array is faster and lighter than an array of objects, which keeps hundreds of cells animating smoothly.
Each frame only a small fraction of cells, set by FLICKER, jump to a new random brightness while the rest hold their value, and brightness is capped at MAXA around 0.55. So most cells stay put on any frame and only a scattered few change, producing a gentle shimmer rather than a harsh strobe.
The loop clears the canvas and fills each cell as a small solid fillRect at its opacity, skipping cells dimmer than a threshold so near-invisible squares cost nothing. Using solid rects instead of per-cell gradients or shadows keeps each frame cheap, which lets a few hundred cells run at 60fps on one canvas.
Yes. It scales with devicePixelRatio capped at 2: the canvas backing buffer is sized up and a setTransform lets drawing happen in CSS pixels while rendering at device resolution, so the square edges stay crisp. The grid also rebuilds on resize, recomputing the cell count for the new dimensions.
Put the canvas behind your content with a ref and run build plus the rAF draw loop in a mount effect, cancelling the frame and removing the resize listener on unmount. Keep the cells typed array and dimensions in refs, not state. The component is framework-agnostic; in Tailwind position the canvas absolute inset-0 behind a relative content layer with a vignette overlay.