Distortion✨ Premium

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.

CSSAnimationOrganic

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

Online profiles in a dating app (Lumivelle) — Iridescent Surface example 1

① Online profiles in a dating app (Lumivelle)

WhenIn the "Near you" list, only people who are online get the iridescent ring around their photo; the others keep a plain grey outline and the time of their last visit.
WhyThe moving hues draw the eye to whoever is available right now, without yet another badge or green dot.
Settings50 px ring, 3 px rim, --irs-inner set to the row colour (#1a1622), transparent root background, 40 px avatar placed inside .irs-ring instead of the word.
Timer for a guided breathing session (Halenna) — Iridescent Surface example 2

② Timer for a guided breathing session (Halenna)

WhenDuring a heart-coherence exercise the ring surrounds the time left; next to it the cue switches between "Breathe in" and "Breathe out" and a bar shows the current cycle.
WhyA slow, regular loop goes along with the breathing pace without dictating it, and the number in the middle gets the same gradient.
Settings210 px ring, 5 px rim, word replaced by the time (2.7 rem) with a "remaining" line below. The countdown and the cue are driven by the page, not by the effect.
Large decorative ring behind a mother-of-pearl pendant (Atelier Quessanthe) — Iridescent Surface example 3

③ Large decorative ring behind a mother-of-pearl pendant (Atelier Quessanthe)

WhenOn the light hero of a jewellery maker, a 330 px ring runs off the right edge and frames the pendant photo; headline, copy and button sit on the left.
WhyThe flowing colours echo the sheen of mother-of-pearl; enlarged and thinned, the ring becomes page decoration rather than an object.
Settings--irs-size: 330px, 3 px rim, softer hues (#e07aa8, #e9a65c, #49b9ae), --irs-inner set to the cream background #f5f0ea, loop slowed to 6 s.

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: reduce both 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 #0a0a0f background 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).

Chrome 88+✓ Full (measured)
Firefox 89+✓ Full (measured)
Safari 15+✓ Full (measured in Playwright's WebKit)
Edge 88+✓ Full (Chromium engine)
Safari iOS 15+✓ Full (same engine as Safari)
Chrome Android 88+✓ Full (Chromium engine)

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):

index.html — structure
<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 / propertyDefaultEffect
--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

Yes. Place the image (round, slightly smaller than the ring) inside .irs-ring instead of .irs-text. It sits above the centre patch and the ring stays visible around it.
The centre is not cut out: it is a patch in the --irs-inner colour, dark by default. Give it the exact colour of your background (for example --irs-inner: #f5f0ea).
Yes: --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.