AI CSS Animations

Watercolor Bloom Background

Pigment blooms spread across warm paper one after another, each with the darker rim of real watercolor, mixing where they overlap and fading away. The ragged edges come from an inline SVG filter.

Also known as: watercolor background css, ink bloom animation, paint spread background css.

HTML

<div class="bgx-watercolor-bloom" aria-hidden="true">
  <svg class="bgx-watercolor-bloom-defs" width="0" height="0">
    <filter id="bgx-watercolor-bloom-edge"><feTurbulence type="fractalNoise" baseFrequency="0.04" numOctaves="2" seed="3" /><feDisplacementMap in="SourceGraphic" scale="16" xChannelSelector="R" yChannelSelector="G" /></filter>
  </svg>
  <span></span><span></span><span></span><span></span><span></span>
</div>

CSS

.bgx-watercolor-bloom {
  --c: var(--bgx-color, #3b82f6);
  font-size: var(--bgx-size, 16px);
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: #fbf8f2;
  isolation: isolate;
}
.bgx-watercolor-bloom-defs {
  position: absolute;
}
.bgx-watercolor-bloom span {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: var(--w);
  aspect-ratio: 1.2;
  translate: -50% -50%;
  border-radius: 50%;
  background: radial-gradient(closest-side, var(--p) 0%, var(--p) 55%, var(--rim) 86%, transparent 95%);
  filter: url(#bgx-watercolor-bloom-edge);
  mix-blend-mode: multiply;
  opacity: 0;
  animation: bgx-watercolor-bloom-spread 10s cubic-bezier(0.2, 0.7, 0.3, 1) var(--d) infinite;
}
.bgx-watercolor-bloom span:nth-child(1) { --x: 22%; --y: 38%; --w: 15em; --d: 0s; --p: oklch(from var(--c) 0.8 0.1 calc(h + 0) / 0.45); --rim: oklch(from var(--c) 0.6 0.15 calc(h + 0) / 0.7); }
.bgx-watercolor-bloom span:nth-child(2) { --x: 60%; --y: 62%; --w: 17em; --d: -2s; --p: oklch(from var(--c) 0.82 0.1 calc(h + 60) / 0.45); --rim: oklch(from var(--c) 0.62 0.16 calc(h + 60) / 0.7); }
.bgx-watercolor-bloom span:nth-child(3) { --x: 82%; --y: 28%; --w: 13em; --d: -4s; --p: oklch(from var(--c) 0.86 0.1 calc(h - 60) / 0.45); --rim: oklch(from var(--c) 0.66 0.13 calc(h - 60) / 0.7); }
.bgx-watercolor-bloom span:nth-child(4) { --x: 40%; --y: 20%; --w: 12em; --d: -6s; --p: oklch(from var(--c) 0.86 0.1 calc(h + 130) / 0.45); --rim: oklch(from var(--c) 0.68 0.14 calc(h + 130) / 0.7); }
.bgx-watercolor-bloom span:nth-child(5) { --x: 12%; --y: 78%; --w: 14em; --d: -8s; --p: oklch(from var(--c) 0.8 0.1 calc(h + 30) / 0.45); --rim: oklch(from var(--c) 0.6 0.15 calc(h + 30) / 0.7); }
@keyframes bgx-watercolor-bloom-spread {
  0%   { transform: scale(0.3) rotate(0deg); opacity: 0; }
  10%  { opacity: 1; }
  55%  { transform: scale(1) rotate(12deg); opacity: 1; }
  100% { transform: scale(1.06) rotate(16deg); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .bgx-watercolor-bloom, .bgx-watercolor-bloom *, .bgx-watercolor-bloom::before, .bgx-watercolor-bloom::after, .bgx-watercolor-bloom *::before, .bgx-watercolor-bloom *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Customizing this snippet

  • Color: set --bgx-color on the element or a parent. Currently previewing #3b82f6.
  • Pattern scale: set --bgx-size. Every other dimension is in em, so the whole thing scales together. Currently previewing 16px.
  • Speed: change the duration on the transition or animation shorthand. Staggered delays are relative, so they keep their rhythm.
  • Reduced motion: the rule at the end of the CSS turns the motion off for people who asked their OS for less of it. Keep it.

Similar animated backgrounds