← SVG2PNG Blog

SVG Patterns: The Background Trick That Saved a Client's Landing Page

Last year a client sent me a landing page mockup with this gorgeous speckled background. Looked like grain on matte paper. They'd built it as a 2400px PNG. The file was 1.8MB. Their Lighthouse performance score was 23. The background alone was blocking the entire page render.

I replaced it with an SVG pattern. 380 bytes. Same visual. Page loaded in under a second.

SVG patterns are one of those things that feel niche until you use them once — then you see opportunities everywhere. They're infinitely scalable, absurdly small, and can do things CSS gradients can't. Here's what I've learned using them in client work.

Why patterns beat PNG backgrounds

A repeating background PNG works at exactly one resolution. On a Retina display it's blurry. On a 4K monitor it looks like a pixel grid. You can export at 2x, but now your file is 4x larger. Export at 3x and it's 9x larger.

SVG patterns render at the display's native resolution — always. A dot pattern is a dot pattern whether you're on a 2007 ThinkPad or a 6K Apple display. And the file size doesn't care about your pattern dimensions. A 4px SVG dot pattern is the same size as a 400px one.

I also prefer SVG patterns for responsive work. Change a CSS background color and the pattern adapts. Want to tweak the spacing? Change one number in the SVG. No re-export, no image pipeline, no @2x sprite sheets.

A dot pattern you can use right now

Dot grids are the most versatile background pattern I know. They add texture without distracting from content. Here's the SVG:

<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
  <pattern id="dots" x="0" y="0" width="16" height="16" patternUnits="userSpaceOnUse">
    <circle cx="8" cy="8" r="1.5" fill="currentColor" opacity="0.15"/>
  </pattern>
  <rect width="100%" height="100%" fill="url(#dots)"/>
</svg>

A few details I learned through trial and error:

Stripes that don't look like a 1998 GeoCities page

Diagonal stripes have a reputation problem. Done wrong they scream "under construction." Done right they're subtle and directional — I use them on hero sections to guide the eye toward the CTA.

<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40">
  <pattern id="stripes" width="40" height="40" patternUnits="userSpaceOnUse"
           patternTransform="rotate(45)">
    <line x1="0" y1="0" x2="0" y2="40" stroke="currentColor" stroke-width="1" opacity="0.06"/>
  </pattern>
  <rect width="100%" height="100%" fill="url(#stripes)"/>
</svg>

The key is the patternTransform="rotate(45)" — it rotates the tile, not each line, so the pattern stays seamless at the edges. Without it you'd need to manually calculate diagonal coordinates that wrap cleanly across the tile boundary.

I've also found that vertical stripes at wider spacing (60–80px tiles) with a single 2px line create a nice ledger-paper effect on finance or data-heavy pages. Horizontal stripes at 8px with 0.03 opacity add a subtle CRT-like texture that works well on dark-mode designs.

Noise and grain textures

This is the one that replaced my client's 1.8MB PNG. SVG noise uses feTurbulence — an SVG filter primitive that generates Perlin noise. Combined with feColorMatrix, you get film-grain texture at any resolution:

<svg xmlns="http://www.w3.org/2000/svg">
  <filter id="noise">
    <feTurbulence type="fractalNoise" baseFrequency="0.65" numOctaves="3" stitchTiles="stitch"/>
    <feColorMatrix type="saturate" values="0"/>
  </filter>
  <rect width="100%" height="100%" filter="url(#noise)" opacity="0.05"/>
</svg>

Three things I adjust per project:

One caution: feTurbulence with high octave counts can cause repaint performance issues on pages with heavy animations. Test on an actual phone — browser support is universal but performance varies. I ran into this on a project with parallax scrolling; the grain + parallax combination dropped to 12fps on a Pixel 6a. Moving the SVG to a static background layer fixed it.

When to convert SVG patterns to PNG instead

As much as I love inline SVG patterns, I don't always recommend them. Here's when I export to PNG instead:

First, when the pattern is part of a brand asset — a logo background, a social media template, anything that needs to look identical everywhere. SVG feTurbulence renders slightly differently across browsers. At 90% of use cases the difference is invisible. But when a brand manager is pixel-peeping, I export a 2x PNG and call it done.

Second, email. Email clients are a CSS time capsule from 2007. Outlook uses Word's rendering engine. Gmail strips <svg> entirely. Background patterns in email must be actual images. I keep a small PNG export of my most-used patterns for this exact reason.

When I do need a PNG version of an SVG pattern, I use SVG2PNG's converter — set the output size to the largest display you're targeting (usually 2560px wide for desktop backgrounds), pick PNG, and you get a clean raster export in seconds.

The 1.8MB PNG I mentioned at the start? After converting the client's page, they asked for the same grain texture on their email newsletter. I exported the SVG at 600px wide PNG — 14KB. That one tiny export handled every email client they tested.

⚡ Quick tip: If you're building patterns in Figma or Illustrator, export them as SVG first. You'll almost always find the code can be simplified — design tools add a lot of namespace cruft and unnecessary precision on coordinates. A 2KB tool-exported SVG often shrinks to 400 bytes after cleanup.

Wrapping up

SVG patterns are one of the highest-leverage techniques in web design — huge visual impact for tiny byte cost. I reach for the dot pattern most often (it just works everywhere), then noise textures when a design needs warmth, then stripes when I need directional energy on a hero.

The common thread across all of these: they're backgrounds. They support content, not compete with it. A pattern that draws attention to itself is a pattern that failed. Subtlety is the whole point.

Jamie Park Written by Jamie Park — UI/UX designer. I help teams ship interfaces faster with SVG and CSS. More about me →