Iridescent Surface
A thin ring with pearly colours (pink, orange, turquoise) flowing in a loop around any content: a word, a number, a profile photo.
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Distortion has 31 effects, including 5 free. Explore the category →
3 usage examples



How it works
The .irs-ring disc is painted with a 45° gradient (pink #ff0080, orange #ff8c00, turquoise #40e0d0) three times its size. The irsFlow animation slides that gradient from one edge to the other and back in 4 seconds, so the hues appear to run along the circle.
It is not a real hole: a ::before pseudo-element covers the disc with a solid patch in the --irs-inner colour, inset by --irs-ring (4 px). Only the rim stays visible, which means the centre must match the background the ring sits on.
Whatever you put inside .irs-ring sits above that patch and stays centred. The supplied word, .irs-text ("IRIS"), reuses the gradient clipped to its letters and animated in the opposite direction. It is real text in the HTML, so you change it without touching the CSS.
Accessibility
- Real text: the central word lives in the HTML (it used to be written in the CSS, out of reach of screen readers). A photo or icon placed in the centre keeps its own alternative text.
- Reduced motion: with
prefers-reduced-motion: reduceboth animations stop; the ring and the word stay on screen at the middle of the gradient (measured: 4 looping animations → 0 for two copies). - No flashing: only the hues slide, slowly (4 s per round trip), with no sudden change in brightness.
- Contrast: on the default
#0a0a0fbackground the word's three hues reach 5.2:1 (pink), 8.5:1 (orange) and 12:1 (turquoise). On a light background, pick darker hues. - No interaction: nothing reacts to hover, click or keyboard, so the ring needs no touch or keyboard equivalent.
Browser compatibility
CSS only, no JavaScript. Measured in Chromium 151, Firefox 153 and Playwright's WebKit 26.5: 0 errors, two independent copies, nothing overflowing at 390 px, animations stopped under reduced motion. The minimum versions come from aspect-ratio (keeps the ring round when it shrinks).
Without aspect-ratio the disc only takes the height of its content and the ring turns oval: add height:var(--irs-size) to .irs-ring for older browsers.
The code
HTML structure to paste into your page (the CSS + JS come with your purchase):
<div class="fx-0262-root">
<div class="irs-ring">
<span class="irs-text">IRIS</span>
</div>
</div>
One-time payment, no subscription — the code is yours forever
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
--irs-size |
250px |
Ring diameter. It never gets wider than its container and stays round. |
--irs-ring |
4px |
Thickness of the visible rim. |
--irs-c1, --irs-c2, --irs-c3 |
#ff0080, #ff8c00, #40e0d0 |
The three gradient hues, shared by the ring and the word. |
--irs-inner |
#0a0a0f |
Colour of the patch covering the centre: use the colour of the background behind the ring. |
--irs-speed |
4s |
Length of one round trip of the colours. |
--irs-font |
1.5rem |
Size of the .irs-text word. |
--irs-bg and --irs-min-h |
#0a0a0f and 300px |
Root background and minimum height; use transparent and 0 to drop the ring into your own layout. |
Content of .irs-ring |
<span class="irs-text">IRIS</span> |
Swap the word for a number, a round photo or an icon: any child is drawn above the centre. |
FAQ
.irs-ring instead of .irs-text. It sits above the centre patch and the ring stays visible around it.--irs-inner colour, dark by default. Give it the exact colour of your background (for example --irs-inner: #f5f0ea).--irs-size: 100% makes it follow the container width, and its height follows thanks to aspect-ratio. Set --irs-min-h: 0 as well so the root stops forcing 300 px.