Four pastel color points drift on looping paths and blend into a soft mesh. One registered @property angle drives every point through sin() and cos(), so the loop is exact.
Also known as: moving mesh gradient css, animated mesh gradient, mesh gradient animation.
<div class="bgx-mesh-gradient" aria-hidden="true"></div>
@property --bgx-mesh-gradient-t {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
.bgx-mesh-gradient {
--c: var(--bgx-color, #3b82f6);
font-size: var(--bgx-size, 16px);
position: absolute;
inset: 0;
overflow: hidden;
background-color: oklch(from var(--c) 0.97 0.015 calc(h + 0));
background-image:
radial-gradient(at calc(18% + 14% * cos(var(--bgx-mesh-gradient-t))) calc(22% + 18% * sin(var(--bgx-mesh-gradient-t))), oklch(from var(--c) 0.76 0.15 calc(h + 0)) 0, transparent 55%),
radial-gradient(at calc(84% - 12% * sin(var(--bgx-mesh-gradient-t))) calc(18% + 16% * cos(var(--bgx-mesh-gradient-t))), oklch(from var(--c) 0.8 0.13 calc(h + 70)) 0, transparent 52%),
radial-gradient(at calc(68% + 16% * cos(var(--bgx-mesh-gradient-t) * 2)) calc(86% - 14% * sin(var(--bgx-mesh-gradient-t))), oklch(from var(--c) 0.84 0.12 calc(h - 70)) 0, transparent 55%),
radial-gradient(at calc(24% - 14% * sin(var(--bgx-mesh-gradient-t) * 2)) calc(82% + 10% * cos(var(--bgx-mesh-gradient-t))), oklch(from var(--c) 0.86 0.1 calc(h + 150)) 0, transparent 50%);
animation: bgx-mesh-gradient-orbit 14s linear infinite;
}
@keyframes bgx-mesh-gradient-orbit {
to { --bgx-mesh-gradient-t: 360deg; }
}
@media (prefers-reduced-motion: reduce) {
.bgx-mesh-gradient, .bgx-mesh-gradient *, .bgx-mesh-gradient::before, .bgx-mesh-gradient::after, .bgx-mesh-gradient *::before, .bgx-mesh-gradient *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--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.