SVG✨ Premium

Geometric Tessellation

A mosaic of gradient tiles with randomly picked directions; a slow pulse runs through the grid one tile after another.

CSSGridPattern

Updated

This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. SVG has 30 effects, including 3 free. Explore the category →

3 usage examples

Architecture practice gallery — the mosaic holds the thumbnails' place while they load — Geometric Tessellation example 1

① Architecture practice gallery — the mosaic holds the thumbnails' place while they load

WhenThe projects page opens: the eight gallery slots pulse, then each project photo covers its slot as soon as it is ready.
WhyThe grid has exactly the gallery's shape (4 columns, 2 rows): visitors see where projects will land, and the wave running through it says loading is moving on.
Settingsdata-cols="4" data-rows="2", --gtz-height: 222px, --gtz-color: #a07c4f on --gtz-bg: #ebe5da, --gtz-gap: 4px. Thumbnails sit in a same-shaped grid on top; the scene simulates their arrival.
Coworking “Plans” section — a teal mosaic behind three price cards — Geometric Tessellation example 2

② Coworking “Plans” section — a teal mosaic behind three price cards

WhenVisitors reach the pricing: the mosaic fills the whole section and ripples slowly behind the Hot desk, Private office and Meeting room cards.
WhyTwelve columns of small tiles read like an office floor plan seen from above; a dark fade at the top keeps the heading readable and the cards have their own background.
Settingsdata-cols="12" data-rows="8", --gtz-height: 360px, --gtz-color: #2dd4bf, --gtz-bg: #061413, --gtz-gap: 3px, root set to position: absolute; inset: 0 under the content.
A local paper's daily sliding puzzle — the board lights up once solved — Geometric Tessellation example 3

③ A local paper's daily sliding puzzle — the board lights up once solved

WhenThe player slides the last tile: the board turns dark and the amber mosaic shows through the sixteen tiles, now transparent.
WhyThe reward takes the shape of the game itself: a 4 × 4 mosaic fitted under the tiles that switches on, instead of a congratulations pop-up.
Settingsdata-cols="4" data-rows="4", --gtz-height: 224px, --gtz-color: #f59e0b, --gtz-bg: #1c1206, --gtz-gap: 2px. The root starts at opacity: 0 and goes to 1 when the scene adds the win class.

How it works

The HTML only holds an empty .gtz-grid container. On load, the script visits every .fx-0610-root on the page and builds data-cols × data-rows tiles inside it (8 × 6 = 48 by default). Each tile gets two variables: its index --gtz-i and an angle --gtz-angle drawn between 0 and 360°. The tile's ::before paints a linear-gradient in that direction, from indigo #6366f1 to transparent at 70%, so no two neighbours look alike and the pattern changes on every load.

The gtzPulse animation takes each tile from 30% to 100% opacity and from 80% to 100% of its size, then back, over 4 seconds. The start time is computed in CSS: calc(var(--gtz-i) * var(--gtz-step) - 100 * var(--gtz-speed)). With 0.05 s between two tiles, the pulse moves in reading order, left to right then row by row. Subtracting 100 cycles makes every delay negative, so the wave is already running when the grid appears: no tile sits fully lit and then drops during the first seconds.

The script keeps no state and puts nothing on window: two mosaics on one page each get their own tiles and angles. It flags the root with data-gtz-ready so pasting the code twice does not fill it twice. Sizes come from the CSS grid, which spans the parent's width over the --gtz-height height (300 px by default).

Accessibility

  • Decoration hidden from screen readers: the grid carries aria-hidden="true". If the mosaic stands for a loading state, announce it next to it with text in an aria-live="polite" region ("Loading projects").
  • Reduced motion: under prefers-reduced-motion: reduce, the animations are paused (animation-play-state: paused). Thanks to the negative delays, the mosaic freezes on a frame where tiles keep different opacities instead of 48 identical squares.
  • No interaction: nothing is clickable or hoverable, the mosaic never takes focus and stays out of the way of keyboard navigation.
  • Contrast: tiles drop to 30% opacity. Text placed on top needs its own background (card, strip); do not rely on the mosaic to make it stand out.

Browser compatibility

CSS Grid, CSS variables and calc() inside animation-delay, no canvas and no library. Minimum versions taken from MDN compatibility data (Grid: Chrome 57, Firefox 52, Safari 10.1). Measured in Chromium 151, Firefox 153 and WebKit 26.5: 48 tiles per copy, two independent copies, nothing overflowing at 390 px.

Chrome 57+✓ Full (measured)
Firefox 52+✓ Full (measured)
Safari 10.1+✓ Full (measured on WebKit)
Edge 79+✓ Full (Chrome engine)
Safari iOS 10.3+✓ Not checked on a device
Chrome Android 57+✓ Full (measured at 390 px, touch)

Without JavaScript the grid stays empty and only the root background shows. Without CSS Grid the tiles have no height and the area stays empty.

The code

HTML structure to paste into your page (the CSS + JS come with your purchase):

index.html — structure
<div class="fx-0610-root" data-cols="8" data-rows="6">
  <div class="gtz-grid" aria-hidden="true"></div>
</div>

One-time payment, no subscription — the code is yours forever

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
data-cols / data-rows (root) 8 / 6 Number of columns and rows (1 to 40). The grid shares the available width and height, so tiles stretch to match their ratio.
--gtz-color #6366f1 Start colour of every gradient; the other end is always transparent and lets --gtz-bg through.
--gtz-bg #0a0a0f Root background, visible between tiles and in their transparent part. A light background with a mid colour gives a skeleton-loader look.
--gtz-gap 2px Inset of each gradient inside its cell: 0 makes tiles touch, 6 px draws a strong grid.
--gtz-speed 4s Length of one full pulse (dim → lit → dim).
--gtz-step 0.05s Offset between two consecutive tiles. 0 pulses the whole grid together; 0.2 s stretches the wave.
--gtz-height 300px Height of the mosaic; the width always follows the parent.

FAQ

Not without editing the script: angles come from Math.random() on every load. For a fixed pattern, replace that value with something derived from the index, such as (i * 47) % 360.
Tiles are built and cleared by the script; they are not meant to hold content. Place a same-shaped grid on top of the root instead, as in the gallery example: the mosaic stays underneath and shows wherever your content has not arrived yet.
Each tile is a CSS opacity and transform animation that the browser hands to the graphics card. A few hundred stay smooth. The script caps the grid at 40 × 40, which is 1,600 animations: near that maximum, especially on mobile, use bigger tiles.