Skip to content
· 13 min read · 0 views

CSS Background Animations — 10 Atmospheric Effects with Code

Build 10 CSS background effects from scratch: gradient shift, floating particles, aurora, ripple, bubbles, confetti, grid pulse, mesh gradient, matrix rain, and starfield. Full copy-paste code for each.

// table of contents (21 sections)

Try them live — All 10 background effects are available on CSSKit where you can customize parameters and copy the code. Source code on GitHub. See the full series: Loading Part 1, Loading Part 2, Hover Part 1.


Background animations transform static pages into immersive experiences. Unlike hover or loading effects that work on individual elements, background effects fill entire sections — hero areas, cards, or full-page atmospheres. In this post, we’ll build 10 CSS background animations that are pure CSS, GPU-friendly, and production-ready.

69. Gradient Shift

Slowly shifting gradient background — the most versatile ambient effect.

How It Works

A linear-gradient at -45deg uses three colors with the first color repeated at the end for seamless looping. The key is background-size: 400% 400% — this makes the gradient four times larger than the element, so animating background-position moves through a massive color field. The ease timing creates a natural breathing rhythm.

.gradient-shift {
  --gs-color-1: #0f0c29;
  --gs-color-2: #302b63;
  --gs-color-3: #24243e;
  --gs-speed: 8s;
  width: 100%;
  height: 200px;
  background: linear-gradient(
    -45deg,
    var(--gs-color-1),
    var(--gs-color-2),
    var(--gs-color-3),
    var(--gs-color-1)
  );
  background-size: 400% 400%;
  animation: gs-shift var(--gs-speed) ease infinite;
  border-radius: 12px;
}

@keyframes gs-shift {
  0% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}
<div class="gradient-shift"></div>

Tip: Use #ff6b6b, #feca57, #48dbfb for a warm sunset gradient, or #0f0c29, #302b63, #24243e for a deep purple night sky.


70. Floating Particles

CSS-only floating particle dots rising through the scene — ambient and dreamy.

How It Works

Eight particles are positioned at different left percentages. Each animates from bottom: -10% to bottom: 110%, rising through the container. A subtle translateX oscillation (±20px) at 50% adds a drift. Each particle has a unique animation-duration (6-11s) and animation-delay, creating organic variation so no two particles move identically.

.floating-particles {
  --fp-color: #818cf8;
  --fp-size: 6px;
  width: 100%;
  height: 200px;
  position: relative;
  overflow: hidden;
  border-radius: 12px;
  background: #111827;
}

.fp-particle {
  position: absolute;
  width: var(--fp-size);
  height: var(--fp-size);
  background: var(--fp-color);
  border-radius: 50%;
  opacity: 0;
  animation: fp-float linear infinite;
}

.fp-particle:nth-child(1) { left: 10%; animation-duration: 7s; animation-delay: 0s; }
.fp-particle:nth-child(2) { left: 25%; animation-duration: 9s; animation-delay: 1s; }
.fp-particle:nth-child(3) { left: 40%; animation-duration: 6s; animation-delay: 2s; }
.fp-particle:nth-child(4) { left: 55%; animation-duration: 8s; animation-delay: 0.5s; }
.fp-particle:nth-child(5) { left: 70%; animation-duration: 10s; animation-delay: 3s; }
.fp-particle:nth-child(6) { left: 85%; animation-duration: 7.5s; animation-delay: 1.5s; }
.fp-particle:nth-child(7) { left: 15%; animation-duration: 11s; animation-delay: 2.5s; }
.fp-particle:nth-child(8) { left: 50%; animation-duration: 6.5s; animation-delay: 4s; }

@keyframes fp-float {
  0% { bottom: -10%; opacity: 0; transform: translateX(0); }
  10% { opacity: 0.6; }
  50% { opacity: 0.3; transform: translateX(20px); }
  90% { opacity: 0.6; }
  100% { bottom: 110%; opacity: 0; transform: translateX(-20px); }
}
<div class="floating-particles">
  <div class="fp-particle"></div><div class="fp-particle"></div><div class="fp-particle"></div>
  <div class="fp-particle"></div><div class="fp-particle"></div><div class="fp-particle"></div>
  <div class="fp-particle"></div><div class="fp-particle"></div>
</div>

Tip: Add box-shadow: 0 0 6px var(--fp-color) to each particle for a glowing effect.


71. Aurora

Northern lights effect with layered radial gradients and mix-blend-mode: screen.

How It Works

Three layers of radial gradients (::before, ::after, and .aurora-glow) each use filter: blur(60-80px) and mix-blend-mode: screen to blend additively. Each layer animates independently with different timing and rotation, creating the flowing aurora motion. The gradients are 200% the container size to avoid edge clipping during movement.

.aurora {
  --au-color-1: #00ff87;
  --au-color-2: #60efff;
  --au-color-3: #0061ff;
  --au-speed: 6s;
  width: 100%;
  height: 200px;
  position: relative;
  overflow: hidden;
  border-radius: 12px;
  background: #0a0a0a;
}

.aurora::before,
.aurora::after {
  content: "";
  position: absolute;
  width: 200%;
  height: 200%;
  top: -50%;
  left: -50%;
  border-radius: 50%;
  filter: blur(60px);
  mix-blend-mode: screen;
  animation: au-move var(--au-speed) ease-in-out infinite alternate;
}

.aurora::before {
  background: radial-gradient(circle, var(--au-color-1) 0%, transparent 50%);
}

.aurora::after {
  background: radial-gradient(circle, var(--au-color-2) 0%, transparent 50%);
  animation-delay: calc(var(--au-speed) * -0.5);
  animation-direction: alternate-reverse;
}

.aurora-glow {
  position: absolute;
  width: 200%;
  height: 200%;
  top: -50%;
  left: -50%;
  border-radius: 50%;
  background: radial-gradient(circle, var(--au-color-3) 0%, transparent 50%);
  filter: blur(80px);
  mix-blend-mode: screen;
  animation: au-move calc(var(--au-speed) * 1.3) ease-in-out infinite alternate;
  animation-delay: calc(var(--au-speed) * -0.3);
}

@keyframes au-move {
  0% { transform: translate(-20%, -20%) rotate(0deg); }
  33% { transform: translate(10%, -10%) rotate(120deg); }
  66% { transform: translate(-10%, 10%) rotate(240deg); }
  100% { transform: translate(20%, 20%) rotate(360deg); }
}
<div class="aurora">
  <div class="aurora-glow"></div>
</div>

Tip: The mix-blend-mode: screen is essential — it makes overlapping colors additive (brighter where they overlap) rather than opaque. Without it, layers would cover each other.


72. Ripple

Expanding ripple circles from center — water-drop effect.

How It Works

Four border-only circles start at the center (10px diameter) and expand to 300px while fading from opacity: 1 to 0. Each circle has a staggered delay using calc(var(--rp-speed) * 0.3/0.6/0.9), creating continuous waves. The ease-out timing makes each wave expand quickly then slow down, mimicking real water ripples that lose energy as they spread.

.ripple {
  --rp-color: #22d3ee;
  --rp-speed: 2s;
  width: 100%;
  height: 200px;
  position: relative;
  overflow: hidden;
  border-radius: 12px;
  background: #0f172a;
}

.ripple-circle {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 10px;
  height: 10px;
  border: 2px solid var(--rp-color);
  border-radius: 50%;
  animation: rp-expand var(--rp-speed) ease-out infinite;
}

.ripple-circle:nth-child(2) { animation-delay: calc(var(--rp-speed) * 0.3); }
.ripple-circle:nth-child(3) { animation-delay: calc(var(--rp-speed) * 0.6); }
.ripple-circle:nth-child(4) { animation-delay: calc(var(--rp-speed) * 0.9); }

@keyframes rp-expand {
  0% { width: 10px; height: 10px; opacity: 1; }
  100% { width: 300px; height: 300px; opacity: 0; }
}
<div class="ripple">
  <div class="ripple-circle"></div>
  <div class="ripple-circle"></div>
  <div class="ripple-circle"></div>
  <div class="ripple-circle"></div>
</div>

Tip: Use border-width: 1px for finer ripples, or 4px for bolder waves. Adjust the 300px max size based on your container width.


73. Bubbles

Translucent bubbles rising slowly — calm and ambient.

How It Works

Five circles of different sizes (20-55px) start below the container (bottom: -20px) and rise to bottom: 110%. Each has a unique animation-duration (scaled with calc(var(--bb-speed) * multiplier)) and a horizontal drift via translateX. The low opacity: 0.12 makes them translucent and glassy. The ease-in timing accelerates as they rise, like real bubbles in water.

.bg-bubbles {
  --bb-color: #3b82f6;
  --bb-speed: 6s;
  position: relative;
  width: 300px;
  height: 200px;
  overflow: hidden;
  background: #050b18;
  border-radius: 12px;
}

.bg-bubbles-bubble {
  position: absolute;
  bottom: -20px;
  border-radius: 50%;
  background: var(--bb-color);
  opacity: 0.12;
  animation: bb-rise var(--bb-speed) ease-in infinite;
}

.bg-bubbles-bubble:nth-child(1) { width: 40px; height: 40px; left: 10%; animation-duration: var(--bb-speed); animation-delay: 0s; }
.bg-bubbles-bubble:nth-child(2) { width: 25px; height: 25px; left: 30%; animation-duration: calc(var(--bb-speed) * 1.3); animation-delay: 1s; }
.bg-bubbles-bubble:nth-child(3) { width: 55px; height: 55px; left: 55%; animation-duration: calc(var(--bb-speed) * 0.9); animation-delay: 0.5s; }
.bg-bubbles-bubble:nth-child(4) { width: 20px; height: 20px; left: 75%; animation-duration: calc(var(--bb-speed) * 1.1); animation-delay: 2s; }
.bg-bubbles-bubble:nth-child(5) { width: 35px; height: 35px; left: 90%; animation-duration: calc(var(--bb-speed) * 1.2); animation-delay: 1.5s; }

@keyframes bb-rise {
  0% { bottom: -20px; transform: translateX(0); }
  50% { transform: translateX(15px); }
  100% { bottom: 110%; transform: translateX(-10px); }
}
<div class="bg-bubbles"><div class="bg-bubbles-bubble"></div><div class="bg-bubbles-bubble"></div><div class="bg-bubbles-bubble"></div><div class="bg-bubbles-bubble"></div><div class="bg-bubbles-bubble"></div></div>

Tip: Add border: 1px solid rgba(255,255,255,0.1) to each bubble for a glass-edge effect.


74. Confetti

Colorful confetti pieces falling with gentle rotation — celebration and festive.

How It Works

Ten pieces with different colors, sizes, and shapes (rectangles and circles via border-radius: 50%). Each falls from top: -10px to top: 110% while rotating a full 360deg and drifting horizontally via translateX. The mixed shapes (some rectangular, some round) and varied colors create an authentic confetti look. Different animation-duration values add natural variation.

.bg-confetti-piece {
  position: absolute;
  top: -10px;
  width: 8px;
  height: 12px;
  border-radius: 2px;
  animation: bcf-fall var(--bcf-speed) ease-in infinite;
}

.bg-confetti-piece:nth-child(1) { left: 8%; background: #ef4444; animation-delay: 0s; animation-duration: calc(var(--bcf-speed) * 0.9); }
.bg-confetti-piece:nth-child(2) { left: 22%; background: #3b82f6; animation-delay: 0.3s; width: 6px; height: 6px; border-radius: 50%; }
.bg-confetti-piece:nth-child(3) { left: 38%; background: #fbbf24; animation-delay: 0.6s; animation-duration: calc(var(--bcf-speed) * 1.1); }
.bg-confetti-piece:nth-child(4) { left: 52%; background: #22c55e; animation-delay: 0.1s; width: 10px; height: 8px; }
.bg-confetti-piece:nth-child(5) { left: 68%; background: #a855f7; animation-delay: 0.8s; animation-duration: calc(var(--bcf-speed) * 0.8); }

@keyframes bcf-fall {
  0% { top: -10px; transform: rotate(0deg) translateX(0); opacity: 1; }
  25% { transform: rotate(90deg) translateX(15px); }
  50% { transform: rotate(180deg) translateX(-10px); }
  75% { transform: rotate(270deg) translateX(8px); opacity: 0.7; }
  100% { top: 110%; transform: rotate(360deg) translateX(0); opacity: 0; }
}
<div class="bg-confetti"><div class="bg-confetti-piece"></div><div class="bg-confetti-piece"></div><div class="bg-confetti-piece"></div><div class="bg-confetti-piece"></div><div class="bg-confetti-piece"></div></div>

Tip: Trigger this on a button click by toggling a class instead of infinite — perfect for “success” celebrations after form submissions.


75. Grid Pulse

Dot grid with a ripple pulse wave — tech and futuristic style.

How It Works

A CSS Grid of 70 dots (10 columns x 7 rows) creates the grid. Each dot pulses between dim (rgba with 0.15 opacity) and bright (full var(--bgp-color)) with a sequential delay of 0.03s per dot. This creates a wave that sweeps across the grid. The scale(1.8) at the pulse peak makes the active dot physically larger, enhancing the wave visibility.

.bg-grid-pulse {
  --bgp-color: #3b82f6;
  --bgp-speed: 2s;
  position: relative;
  width: 280px;
  height: 180px;
  overflow: hidden;
  background: #050b18;
  border-radius: 12px;
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  grid-template-rows: repeat(7, 1fr);
  gap: 4px;
  padding: 12px;
}

.bg-grid-pulse-dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: rgba(59, 130, 246, 0.2);
  align-self: center;
  justify-self: center;
  animation: bgp-pulse var(--bgp-speed) ease-in-out infinite;
}

.bg-grid-pulse-dot:nth-child(1) { animation-delay: 0s; }
.bg-grid-pulse-dot:nth-child(2) { animation-delay: 0.03s; }
.bg-grid-pulse-dot:nth-child(3) { animation-delay: 0.06s; }
/* ... continue for all 70 dots with 0.03s increments */

@keyframes bgp-pulse {
  0%, 100% { background: rgba(59, 130, 246, 0.15); transform: scale(1); }
  50% { background: var(--bgp-color); transform: scale(1.8); }
}
<div class="bg-grid-pulse">
  <div class="bg-grid-pulse-dot"></div><!-- x70 dots -->
</div>

Tip: Generate the HTML and CSS dynamically with JavaScript for larger grids. The 0.03s delay per dot creates the sweep speed.


76. Mesh Gradient

Slowly morphing multi-color mesh gradient — modern and organic.

How It Works

Similar to the gradient-shift but with four keyframe stops instead of three, moving the background-position in a diamond pattern: 0% 50%100% 50%100% 0%0% 100% → back. This creates a more complex path through the color space, making the morphing feel less linear and more organic. The 400% 400% background-size provides plenty of gradient to travel through.

.bg-mesh-gradient {
  --bmg-c1: #3b82f6;
  --bmg-c2: #8b5cf6;
  --bmg-c3: #06b6d4;
  --bmg-speed: 8s;
  width: 300px;
  height: 200px;
  border-radius: 12px;
  background: linear-gradient(135deg, var(--bmg-c1), var(--bmg-c2), var(--bmg-c3), var(--bmg-c1));
  background-size: 400% 400%;
  animation: bmg-morph var(--bmg-speed) ease infinite;
}

@keyframes bmg-morph {
  0% { background-position: 0% 50%; }
  25% { background-position: 100% 50%; }
  50% { background-position: 100% 0%; }
  75% { background-position: 0% 100%; }
  100% { background-position: 0% 50%; }
}
<div class="bg-mesh-gradient"></div>

Tip: The simplest effect to implement — one div, no pseudo-elements, no extra HTML. Great for hero sections and card backgrounds.


77. Matrix Rain

Digital rain drops falling like the Matrix — cyberpunk themed.

How It Works

Ten thin vertical lines (width: 2px) with a gradient from transparent to the accent color. Each falls from top: -30px to top: 110% with different speeds and delays. The linear timing maintains constant fall speed. Varying heights (15-30px) and speeds (0.6x to 1.2x the base speed) create the random-appearing cascade of the Matrix effect.

.bg-rain-drop {
  position: absolute;
  top: -30px;
  width: 2px;
  height: 20px;
  background: linear-gradient(to bottom, transparent, var(--br-color));
  border-radius: 1px;
  animation: br-fall var(--br-speed) linear infinite;
}

.bg-rain-drop:nth-child(1) { left: 10%; animation-duration: calc(var(--br-speed) * 1.0); height: 18px; }
.bg-rain-drop:nth-child(2) { left: 25%; animation-duration: calc(var(--br-speed) * 0.8); animation-delay: 0.3s; height: 25px; }
.bg-rain-drop:nth-child(3) { left: 40%; animation-duration: calc(var(--br-speed) * 1.1); animation-delay: 0.1s; }

@keyframes br-fall {
  0% { top: -30px; opacity: 1; }
  80% { opacity: 0.5; }
  100% { top: 110%; opacity: 0; }
}
<div class="bg-rain"><div class="bg-rain-drop"></div><div class="bg-rain-drop"></div><div class="bg-rain-drop"></div><div class="bg-rain-drop"></div><div class="bg-rain-drop"></div><div class="bg-rain-drop"></div><div class="bg-rain-drop"></div><div class="bg-rain-drop"></div><div class="bg-rain-drop"></div><div class="bg-rain-drop"></div></div>

Tip: Change the color to #22d3ee (cyan) for a Tron-style digital rain, or #f472b6 (pink) for a synthwave aesthetic.


78. Starfield

Twinkling stars at different depths — space-themed parallax.

How It Works

Twelve dots scattered at random positions. Each twinkles between opacity: 0.2; scale(1) and opacity: 1; scale(1.5) with staggered delays. Some stars are larger (3px vs 2px) to simulate depth — bigger stars appear closer. The ease-in-out timing creates a gentle breathing twinkle rather than a harsh flash.

.bg-stars-star {
  position: absolute;
  width: 2px;
  height: 2px;
  border-radius: 50%;
  background: var(--bst-color);
  animation: bst-twinkle var(--bst-speed) ease-in-out infinite;
}

.bg-stars-star:nth-child(1) { top: 15%; left: 20%; animation-delay: 0s; }
.bg-stars-star:nth-child(2) { top: 35%; left: 65%; animation-delay: 0.4s; width: 3px; height: 3px; }
.bg-stars-star:nth-child(3) { top: 55%; left: 10%; animation-delay: 0.8s; }

@keyframes bst-twinkle {
  0%, 100% { opacity: 0.2; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.5); }
}
<div class="bg-stars"><div class="bg-stars-star"></div><div class="bg-stars-star"></div><div class="bg-stars-star"></div><div class="bg-stars-star"></div><div class="bg-stars-star"></div><div class="bg-stars-star"></div><div class="bg-stars-star"></div><div class="bg-stars-star"></div><div class="bg-stars-star"></div><div class="bg-stars-star"></div><div class="bg-stars-star"></div><div class="bg-stars-star"></div></div>

Tip: Add a slow background-position animation to the container itself for a subtle parallax drift effect.


What’s Next?

That’s 10 background effects covering the most popular atmospheric patterns. CSSKit has 22 total — in the next post we’ll cover the remaining 12 including aurora borealis, fireflies, snow, lightning, lava, and plasma effects.

Explore all 310 animations live at CSSKit or star the repo on GitHub.

You might also like

Enjoyed This Post?

Want to discuss the topic, have questions, or looking to collaborate on something similar? Drop a comment below or reach out directly.

Discussion