Two sets of fine rings, one circling slightly off center, interfere into bold moving bands, a classic op art illusion. Only one layer rotates; the bands you see are drawn by the overlap alone.
Also known as: moire effect css, op art background animation, interference pattern css.
<div class="bgx-moire-pattern" aria-hidden="true"></div>
.bgx-moire-pattern {
--c: var(--bgx-color, #3b82f6);
font-size: var(--bgx-size, 16px);
position: absolute;
inset: 0;
overflow: hidden;
--orbit: 2.2em;
container-type: size;
background: color-mix(in srgb, var(--c) 5%, #fff);
}
.bgx-moire-pattern::before,
.bgx-moire-pattern::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
width: calc(150cqmax + var(--orbit) * 3);
height: calc(150cqmax + var(--orbit) * 3);
margin: calc(-75cqmax - var(--orbit) * 1.5) 0 0 calc(-75cqmax - var(--orbit) * 1.5);
background: repeating-radial-gradient(circle, color-mix(in srgb, var(--c) 80%, transparent) 0 0.16em, transparent 0.2em 0.6em);
}
.bgx-moire-pattern::after {
transform-origin: calc(50% + var(--orbit)) 50%;
animation: bgx-moire-pattern-orbit 14s linear infinite;
}
@keyframes bgx-moire-pattern-orbit {
to { transform: rotate(1turn); }
}
@media (prefers-reduced-motion: reduce) {
.bgx-moire-pattern, .bgx-moire-pattern *, .bgx-moire-pattern::before, .bgx-moire-pattern::after, .bgx-moire-pattern *::before, .bgx-moire-pattern *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}The same effect using Tailwind utility classes. No custom CSS or config needed.
<div class="absolute inset-0 overflow-hidden bg-white"> <div class="absolute left-1/2 top-1/2 -ml-[80vmax] -mt-[80vmax] h-[160vmax] w-[160vmax] bg-[repeating-radial-gradient(circle,rgb(59_130_246/.75)_0_1.5px,transparent_2px_6px)]"></div> <div class="absolute left-1/2 top-1/2 -ml-[80vmax] -mt-[80vmax] h-[160vmax] w-[160vmax] origin-[calc(50%_+_2rem)_50%] animate-spin bg-[repeating-radial-gradient(circle,rgb(59_130_246/.75)_0_1.5px,transparent_2px_6px)] [animation-duration:14s]"></div> </div>
--bgx-color on the element or a parent.
Currently previewing #3b82f6.--bgx-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 16px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.