Why Wavy Backgrounds Matter in Modern Web Design
Wavy backgrounds have become a distinctive design element in modern web development, adding visual interest and organic flow to otherwise rigid page layouts. From landing page section transitions to creative hero headers, the wave pattern creates a sense of movement and depth that engages users immediately.
In this guide, we explore multiple techniques for creating wavy backgrounds using CSS and SVG, with code examples you can implement in your web development projects today.
What you'll learn:
- CSS-only approaches using pseudo-elements and border-radius
- SVG-based solutions for complex shapes and animations
- Performance best practices for production sites
- Responsive and accessible implementation patterns
CSS-Only Approaches
Pure CSS solutions offer the best performance and simplest implementation for basic wavy effects. This approach requires no external files and renders instantly in the browser.
The Bubble Pattern
The bubble pattern creates an elliptical shape using only CSS pseudo-elements. This approach works well for simple, single-wave designs:
.bubble::after {
content: '';
border-top-left-radius: 50% 100%;
border-top-right-radius: 50% 100%;
position: absolute;
bottom: 0;
z-index: -1;
width: 100%;
background-color: #0f0f10;
height: 85%;
}
The border-radius values control the curvature--50% creates the horizontal curve while 100% creates the vertical extension.
The Wave Pattern
For more complex wavy effects, the wave pattern overlaps two elliptical pseudo-elements:
section {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
min-height: 400px;
background: #3c31dd;
}
.curve::before,
.curve::after {
content: '';
position: absolute;
border-radius: 100% 50%;
width: 55%;
height: 100%;
}
.curve::before {
transform: translate(85%, 60%);
}
.curve::after {
transform: translate(-4%, 40%);
z-index: -1;
}
These CSS techniques are ideal for developers building performance-optimized websites where load time and rendering speed are critical considerations.
Compare different techniques to find the best fit for your project
CSS Pseudo-Elements
Best for simple waves. No external files, instant rendering, excellent performance.
Radial Gradients
Repeatable patterns using CSS masks. Great for consistent wave effects across sections.
Inline SVG
Full control over shapes and animations. Ideal for complex, interactive wave effects.
SVG Background Images
Static decorative waves with browser caching. Good balance of quality and performance.
SVG-Based Solutions
For complex, customizable, or animated wavy backgrounds, SVG provides greater flexibility and enables advanced design possibilities.
Inline SVG Waves
Inline SVG gives you full control and enables CSS animations:
<svg viewBox="0 0 1200 120" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none">
<path d="M321.39,56.44c58-10.79,114.16-30.13,172-41.86..." class="shape-fill"></path>
</svg>
CSS Mask Waves
Advanced gradient-based waves using CSS masks:
.wave {
--size: 50px;
--m: 0.5;
--p: calc(var(--m) * var(--size));
--R: calc(var(--size) * sqrt(var(--m) * var(--m) + 1));
mask:
radial-gradient(var(--R) at 50% calc(var(--size) + var(--p)), #000 99%, #0000 101%)
calc(50% - 2 * var(--size)) 0 / calc(4 * var(--size)) 100%,
radial-gradient(var(--R) at 50% calc(-1 * var(--p)), #0000 99%, #000 101%)
50% var(--size) / calc(4 * var(--size)) 100% repeat-x;
}
Animated Blobs
For dynamic backgrounds using KUTE.js:
const tween = KUTE.fromTo(
'#blob1',
{ path: '#blob1' },
{ path: '#blob2' },
{ repeat: 999, duration: 3000, yoyo: true }
).start();
These SVG techniques pair well with modern responsive web design practices, ensuring your wavy backgrounds look great on all devices.
Performance Best Practices
Optimization Strategies
-
Use CSS-only for simple waves: Pure CSS requires no network requests and renders instantly.
-
Optimize SVG files: Remove metadata, round coordinates, use SVGO for optimization.
-
Implement responsive SVG: Use viewBox and preserveAspectRatio correctly.
-
Lazy load below-fold waves: Defer loading until needed.
-
Use CSS containment: Apply
contain: paintto limit browser reflow calculations.
.wave-section {
contain: paint;
content-visibility: auto;
}
Implementing these performance techniques helps maintain strong Core Web Vitals, which are essential for both user experience and search engine rankings.
Accessibility Considerations
- Maintain sufficient color contrast
- Don't rely solely on wavy shapes for hierarchy
- Provide fallback colors
- Test with screen readers
Implementation in Next.js
For Next.js projects, use component-based patterns:
export default function WaveSection({
children,
waveColor = '#3c31dd',
backgroundColor = '#0f0f10'
}: WaveSectionProps) {
return (
<section style={{ backgroundColor, position: 'relative' }}>
<div style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
height: '100px',
background: `linear-gradient(to bottom right, ${waveColor} 50%, transparent 50%)`,
transform: 'translateY(-99%)'
}} />
{children}
</section>
);
}
This component ensures consistency while allowing customization through props. By creating reusable wave components, you can maintain visual coherence across your entire site while reducing code duplication.
Explore more web development tutorials in our resource library for additional techniques to enhance your projects.