Design & Media

CSS textures

Add depth and surface to a page with zero image files — dots, stripes, grids, checkerboards, graph paper, and even grain, all made from gradients and a tiny inline SVG. They're crisp at any size, weigh nothing, and recolor instantly. Copy any swatch's CSS below.

New to CSS? Read the visual lesson →
Start here

Why CSS textures?

A repeating background made of gradients is sharper, lighter, and more flexible than a texture image — it scales to any resolution, recolors with one value, and adds zero network requests. Almost every pattern is just repeating-linear-gradient, radial-gradient, or conic-gradient on background-image with a background-size.

Weightless

No image downloads — just a few CSS values. Faster pages, every time.

Infinitely crisp

Gradients are vector-sharp at any zoom or screen density. No blur, no pixelation.

Recolor instantly

Change one hex value and the whole texture updates. Great with design tokens.

Tile-able

background-size sets the tile; it repeats seamlessly across any area.

The library

Six textures, copy & paste

Every swatch is a single background. Click Copy on any block to grab it.

// polka dots
// diagonal stripes
// grid lines
// checkerboard
// noise / grain
// graph paper
HTML — the swatch grid (matches the demo above)
<!-- a texture is just a class on a normal element -->
<div class="grid2">
  <div><div class="tx tx-dots"></div><div class="swatch-label">// polka dots</div></div>
  <div><div class="tx tx-stripes"></div><div class="swatch-label">// diagonal stripes</div></div>
  <div><div class="tx tx-grid"></div><div class="swatch-label">// grid lines</div></div>
  <div><div class="tx tx-check"></div><div class="swatch-label">// checkerboard</div></div>
  <div><div class="tx tx-grain"></div><div class="swatch-label">// noise / grain</div></div>
  <div><div class="tx tx-graph"></div><div class="swatch-label">// graph paper</div></div>
</div>
CSS — layout + swatch box (shared by every texture)
.grid2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
@media (max-width: 560px) { .grid2 { grid-template-columns: 1fr; } }

/* every texture sits in this box */
.tx {
  height: 150px;
  border-radius: 12px;
  border: 1px solid #e5e7eb;
}
.swatch-label {
  font-size: .72rem;
  color: #6b7280;
  font-family: 'SF Mono', Consolas, monospace;
  margin-top: 8px;
}
CSS — Polka dots
.tx-dots {
  background-color: #fff;
  background-image: radial-gradient(#5e9ea0 2px, transparent 2px);
  background-size: 20px 20px;           /* dot spacing */
}
CSS — Diagonal stripes
.tx-stripes {
  background: repeating-linear-gradient(45deg,
              #5e9ea0 0 12px, #e6f3f2 12px 24px);   /* color / gap, repeated */
}
CSS — Grid lines
.tx-grid {
  background-color: #fff;
  background-image:
    linear-gradient(#cfe6e4 1px, transparent 1px),          /* horizontal */
    linear-gradient(90deg, #cfe6e4 1px, transparent 1px);   /* vertical   */
  background-size: 24px 24px;
}
CSS — Checkerboard
.tx-check {
  background: conic-gradient(#5e9ea0 90deg, #e6f3f2 0 180deg,
                             #5e9ea0 0 270deg, #e6f3f2 0);
  background-size: 36px 36px;           /* one square pair = half the tile */
}
CSS — Noise / grain
.tx-grain {
  position: relative;       /* anchors the overlay */
  background: #5e9ea0;      /* base color */
}
.tx-grain::after {
  content: ''; position: absolute; inset: 0;
  border-radius: 12px;
  opacity: .35; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
CSS — Graph paper
.tx-graph {
  background-color: #fff;
  background-image:
    linear-gradient(#e6f3f2 1px, transparent 1px),            /* fine lines */
    linear-gradient(90deg, #e6f3f2 1px, transparent 1px),
    linear-gradient(#cfe6e4 1px, transparent 1px),            /* bold lines */
    linear-gradient(90deg, #cfe6e4 1px, transparent 1px);
  background-size: 100px 100px, 100px 100px, 20px 20px, 20px 20px;
}
Pro tips: drive the colors with CSS custom properties so a texture matches your theme, and add background-position or a slow background-position animation for movement. Keep contrast gentle so the texture sits behind content, never fights it.
Reference

Characteristics & components

The signals of a CSS-texture approach:

Texture created with CSS No image backgrounds

The techniques

A gradient, a noise overlay, a pattern, and a layered shadow — live first, then the code.

HTML — the four technique boxes (matches the demo above)
<div class="techniques">
  <div class="grad"></div>
  <div class="noise"></div>
  <div class="dots"></div>
  <div class="shadow"></div>
</div>
CSS
.techniques {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: center;
}
/* every box is the same size */
.techniques > div {
  width: 120px;
  height: 90px;
  border-radius: 12px;
}

/* 1 — Gradient */
.grad { background: radial-gradient(circle at 30% 30%, #7bd8c0, #5e9ea0); }

/* 2 — Noise overlay (inline SVG feTurbulence) */
.noise {
  position: relative;       /* anchors the overlay */
  background: #5e9ea0;
  overflow: hidden;
}
.noise::after {
  content: ''; position: absolute; inset: 0;
  opacity: .4; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* 3 — Pattern (repeating dots) */
.dots {
  background-color: #fff;
  background-image: radial-gradient(#5e9ea0 2px, transparent 2px);
  background-size: 18px 18px;
}

/* 4 — Layered shadow for depth */
.shadow {
  background: #fff;
  box-shadow: 0 2px 4px rgba(0,0,0,.1),
              0 8px 16px rgba(0,0,0,.1),
              0 20px 40px rgba(94,158,160,.3);
}
Recap

The takeaway

Most surface textures are one background away: radial-gradient for dots, repeating-linear-gradient for stripes, stacked linear-gradients for grids and graph paper, conic-gradient for checks, and a tiny SVG feTurbulence for grain. Vector-crisp, weightless, and recolorable — use them to add depth without a single image. See also CSS Recipes.