animated radial gradient

by phloe

HTML

<div></div>

CSS

@property --offset {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 0%;
}

@property --ring-1-fill {
  syntax: '<color>';
  inherits: false;
  initial-value: #FFF;
}

@property --ring-2-fill {
  syntax: '<color>';
  inherits: false;
  initial-value: #FFF;
}

div {
  width: 100%;
  aspect-ratio: 1;
  --fill: #FFF;
  --stroke: calc((20 / 192) * 100%);
  --space: calc((21 / 192) * 100%);
  --offset: calc((var(--space) * 2 + var(--stroke) * 2) * -1);
  mask-image:
    radial-gradient(
    transparent calc(var(--space) + var(--offset)),
    var(--fill) calc((var(--space) * 1 + var(--stroke) * 0 + var(--offset) * 1) + 1px) calc(var(--space) * 1 + var(--stroke) * 1 + var(--offset)),
    transparent calc((var(--space) * 1 + var(--stroke) * 1 + var(--offset)) + 1px) calc(var(--space) * 2 + var(--stroke) * 1 + var(--offset)),
    var(--fill) calc((var(--space) * 2 + var(--stroke) * 1 + var(--offset)) + 1px) calc(var(--space) * 2 + var(--stroke) * 2 + var(--offset)),
    transparent calc((var(--space) * 2 + var(--stroke) * 2 + var(--offset)) + 1px) calc(var(--space) * 3 + var(--stroke) * 2 + var(--offset)),
    var(--ring-2-fill) calc((var(--space) * 3 + var(--stroke) * 2 + var(--offset)) + 1px) calc(var(--space) * 3 + var(--stroke) * 3 + var(--offset)),
    transparent calc((var(--space) * 3 + var(--stroke) * 3 + var(--offset)) + 1px) calc(var(--space) * 4 + var(--stroke) * 3 + var(--offset)),
    var(--ring-1-fill) calc((var(--space) * 4 + var(--stroke) * 3 + var(--offset)) + 1px) calc(var(--space) * 4 + var(--stroke) * 4 + var(--offset)),
      transparent calc((var(--space) * 4 + var(--stroke) * 4 + var(--offset)) + 1px) calc(var(--space) * 5 + var(--stroke) * 4 + var(--offset))
  );
  animation: grow 4s infinite, fade-rings 4s infinite linear;
  background-color: red;
}

@keyframes grow {
  from {
    animation-timing-function: ease-in;
  }
  10% {
    --offset: calc((var(--space) * 2 + var(--stroke) * 1) *...