04 / 14
All 14 in 14 Tailwind CSS Wave Section Dividers
- 01Tailwind CSS SVG Wave Section Divider with Zero Dependencies
- 02Tailwind Animated Wave Section Divider for Landing Pages
- 03Tailwind Responsive SVG Wave Divider at the Bottom of a Hero
- 04Tailwind Stacked Multi Color SVG Wave Section Divider
- 05Tailwind Wave Section Divider Footer Transition
- 06Pure Tailwind Clip Path Wave Divider Without SVG
- 07Tailwind Inverted Curve SVG Wave Divider
- 08Tailwind Wave Divider Full Width Responsive Mobile Fix
- 09Tailwind Gradient Wave Section Divider with a Background Mask
- 10Tailwind Asymmetrical Organic SVG Section Wave
- 11Tailwind Dark Mode Wave Divider Colour Match
- 12Tailwind Animated Sine Wave Section Divider Transition
- 13Tailwind Wave Section Divider with an Overlay Background Image
- 14Tailwind Vertical Wave Divider for Side Navigation
Tailwind Stacked Multi Color SVG Wave Section Divider
Two or three offset waves in tinted layers, so a change of background colour reads as depth instead of a line. The port replaces a ladder of :nth-child() + color-mix() rules with an opacity modifier on each layer’s own fill-* utility.
Complete Tailwind CSS landing page templates in HTML, React, Next.js and Vue · from $49
Cruip · Affiliate link
The code
<section class="twd-04 w-full min-h-svh flex flex-col font-twd04-sans">
<!-- Three tinted layers -->
<div class="relative overflow-hidden bg-twd04-from text-white px-6 pt-18 pb-32 text-center">
<h2 class="text-[clamp(25px,4vw,38px)] font-semibold">Layered depth, one hue</h2>
<div aria-hidden="true" class="absolute inset-x-0 -bottom-px h-[clamp(70px,11vw,130px)] pointer-events-none">
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-to/30" viewBox="0 0 1440 130" preserveAspectRatio="none" focusable="false"><path d="M0,70 C260,20 520,120 780,74 C1040,28 1240,60 1440,40 L1440,130 L0,130 Z"></path></svg>
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-to/62" viewBox="0 0 1440 130" preserveAspectRatio="none" focusable="false"><path d="M0,86 C240,44 500,126 760,88 C1020,50 1250,96 1440,66 L1440,130 L0,130 Z"></path></svg>
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-to" viewBox="0 0 1440 130" preserveAspectRatio="none" focusable="false"><path d="M0,100 C220,70 480,132 740,102 C1000,72 1250,120 1440,92 L1440,130 L0,130 Z"></path></svg>
</div>
</div>
<div class="bg-twd04-to text-twd04-toink px-6 pt-8 pb-16 text-center">
<p class="text-[15px]">Back layers are stepped tints of one hue; only the front layer is opaque.</p>
</div>
<!-- Duotone offset ribbons -->
<div class="relative overflow-hidden bg-twd04-navy text-white px-6 pt-17 pb-29 text-center">
<h2 class="text-[clamp(25px,4vw,38px)] font-semibold">Two-colour ribbon seam</h2>
<div aria-hidden="true" class="absolute inset-x-0 -bottom-px h-[clamp(64px,10vw,120px)] pointer-events-none">
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-accent" viewBox="0 0 1440 120" preserveAspectRatio="none" focusable="false"><path d="M0,54 C300,110 620,6 940,52 C1160,84 1300,92 1440,62 L1440,120 L0,120 Z"></path></svg>
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-shell" viewBox="0 0 1440 120" preserveAspectRatio="none" focusable="false"><path d="M0,74 C300,126 620,22 940,70 C1160,102 1300,110 1440,80 L1440,120 L0,120 Z"></path></svg>
</div>
</div>
<div class="bg-twd04-shell text-twd04-navyink px-6 pt-8 pb-15 text-center">
<p class="text-[15px] max-w-[52ch] mx-auto">An accent ribbon peeks out from under the opaque edge — brand colour, no extra markup weight.</p>
</div>
</section><section class="twd-04 w-full min-h-svh flex flex-col font-twd04-sans">
<!-- Three tinted layers -->
<div class="relative overflow-hidden bg-twd04-from text-white px-6 pt-18 pb-32 text-center">
<h2 class="text-[clamp(25px,4vw,38px)] font-semibold">Layered depth, one hue</h2>
<div aria-hidden="true" class="absolute inset-x-0 -bottom-px h-[clamp(70px,11vw,130px)] pointer-events-none">
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-to/30" viewBox="0 0 1440 130" preserveAspectRatio="none" focusable="false"><path d="M0,70 C260,20 520,120 780,74 C1040,28 1240,60 1440,40 L1440,130 L0,130 Z"></path></svg>
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-to/62" viewBox="0 0 1440 130" preserveAspectRatio="none" focusable="false"><path d="M0,86 C240,44 500,126 760,88 C1020,50 1250,96 1440,66 L1440,130 L0,130 Z"></path></svg>
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-to" viewBox="0 0 1440 130" preserveAspectRatio="none" focusable="false"><path d="M0,100 C220,70 480,132 740,102 C1000,72 1250,120 1440,92 L1440,130 L0,130 Z"></path></svg>
</div>
</div>
<div class="bg-twd04-to text-twd04-toink px-6 pt-8 pb-16 text-center">
<p class="text-[15px]">Back layers are stepped tints of one hue; only the front layer is opaque.</p>
</div>
<!-- Duotone offset ribbons -->
<div class="relative overflow-hidden bg-twd04-navy text-white px-6 pt-17 pb-29 text-center">
<h2 class="text-[clamp(25px,4vw,38px)] font-semibold">Two-colour ribbon seam</h2>
<div aria-hidden="true" class="absolute inset-x-0 -bottom-px h-[clamp(64px,10vw,120px)] pointer-events-none">
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-accent" viewBox="0 0 1440 120" preserveAspectRatio="none" focusable="false"><path d="M0,54 C300,110 620,6 940,52 C1160,84 1300,92 1440,62 L1440,120 L0,120 Z"></path></svg>
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-shell" viewBox="0 0 1440 120" preserveAspectRatio="none" focusable="false"><path d="M0,74 C300,126 620,22 940,70 C1160,102 1300,110 1440,80 L1440,120 L0,120 Z"></path></svg>
</div>
</div>
<div class="bg-twd04-shell text-twd04-navyink px-6 pt-8 pb-15 text-center">
<p class="text-[15px] max-w-[52ch] mx-auto">An accent ribbon peeks out from under the opaque edge — brand colour, no extra markup weight.</p>
</div>
</section>@import "tailwindcss";
@theme {
--color-twd04-from: #443a77;
--color-twd04-from: oklch(0.34 0.12 285);
--color-twd04-to: #eeeaf7;
--color-twd04-to: oklch(0.95 0.03 285);
--color-twd04-toink: #4a4173;
--color-twd04-toink: oklch(0.4 0.09 285);
--color-twd04-navy: #17323c;
--color-twd04-navy: oklch(0.24 0.04 200);
--color-twd04-navyink: #2b4b57;
--color-twd04-navyink: oklch(0.38 0.05 200);
--color-twd04-shell: #f6f9fa;
--color-twd04-shell: oklch(0.97 0.01 200);
--color-twd04-accent: #e0a92c;
--color-twd04-accent: oklch(0.75 0.17 88);
--font-twd04-sans: 'Space Grotesk', system-ui, sans-serif;
}
.twd-04 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-twd04-from: #443a77;
--color-twd04-from: oklch(0.34 0.12 285);
--color-twd04-to: #eeeaf7;
--color-twd04-to: oklch(0.95 0.03 285);
--color-twd04-toink: #4a4173;
--color-twd04-toink: oklch(0.4 0.09 285);
--color-twd04-navy: #17323c;
--color-twd04-navy: oklch(0.24 0.04 200);
--color-twd04-navyink: #2b4b57;
--color-twd04-navyink: oklch(0.38 0.05 200);
--color-twd04-shell: #f6f9fa;
--color-twd04-shell: oklch(0.97 0.01 200);
--color-twd04-accent: #e0a92c;
--color-twd04-accent: oklch(0.75 0.17 88);
--font-twd04-sans: 'Space Grotesk', system-ui, sans-serif;
}
.twd-04 {
width: 100%;
min-height: 100svh;
}Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>Compiles in the browser — perfect for a CodePen or a quick test, not for production.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--color-twd04-from: #443a77;
--color-twd04-from: oklch(0.34 0.12 285);
--color-twd04-to: #eeeaf7;
--color-twd04-to: oklch(0.95 0.03 285);
--color-twd04-toink: #4a4173;
--color-twd04-toink: oklch(0.4 0.09 285);
--color-twd04-navy: #17323c;
--color-twd04-navy: oklch(0.24 0.04 200);
--color-twd04-navyink: #2b4b57;
--color-twd04-navyink: oklch(0.38 0.05 200);
--color-twd04-shell: #f6f9fa;
--color-twd04-shell: oklch(0.97 0.01 200);
--color-twd04-accent: #e0a92c;
--color-twd04-accent: oklch(0.75 0.17 88);
--font-twd04-sans: 'Space Grotesk', system-ui, sans-serif;
}
.twd-04 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-twd04-from: #443a77;
--color-twd04-from: oklch(0.34 0.12 285);
--color-twd04-to: #eeeaf7;
--color-twd04-to: oklch(0.95 0.03 285);
--color-twd04-toink: #4a4173;
--color-twd04-toink: oklch(0.4 0.09 285);
--color-twd04-navy: #17323c;
--color-twd04-navy: oklch(0.24 0.04 200);
--color-twd04-navyink: #2b4b57;
--color-twd04-navyink: oklch(0.38 0.05 200);
--color-twd04-shell: #f6f9fa;
--color-twd04-shell: oklch(0.97 0.01 200);
--color-twd04-accent: #e0a92c;
--color-twd04-accent: oklch(0.75 0.17 88);
--font-twd04-sans: 'Space Grotesk', system-ui, sans-serif;
}
.twd-04 {
width: 100%;
min-height: 100svh;
}<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&display=swap">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
.layer:nth-child(2) path{fill:color-mix(in oklab,var(--to) 62%,transparent)}becomesfill-twd04-to/62. This is the clearest single-line improvement in the whole port: the tint ladder is now visible as a ladder.- Because the layers are
<svg>elements rather than paths,fill-*works directly and no[&_path]:variant is needed — fill inherits into the path. - No
z-indexutilities appear anywhere. DOM order is the stacking order for positioned siblings, and spelling it out would only create something to keep in sync. - UI change from the CSS original: the caption under each stack was
opacity:.75mid-grey on near-white, roughly 3.4:1. Both now use dedicated full-opacity ink tokens (--color-twd04-toink,--color-twd04-navyink) that clear 4.5:1.
Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Stacked Multi Color SVG Wave Section Divider
Source: https://codefronts.com/layouts/tailwind-css-wave-section-dividers/tailwind-stacked-multi-color-svg-wave-section-divider/
Two or three offset waves in tinted layers, so a change of background colour reads as depth instead of a line. The port replaces a ladder of :nth-child() + color-mix() rules with an opacity modifier on each layer’s own fill-* utility.
## HTML
```html
<section class="twd-04 w-full min-h-svh flex flex-col font-twd04-sans">
<!-- Three tinted layers -->
<div class="relative overflow-hidden bg-twd04-from text-white px-6 pt-18 pb-32 text-center">
<h2 class="text-[clamp(25px,4vw,38px)] font-semibold">Layered depth, one hue</h2>
<div aria-hidden="true" class="absolute inset-x-0 -bottom-px h-[clamp(70px,11vw,130px)] pointer-events-none">
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-to/30" viewBox="0 0 1440 130" preserveAspectRatio="none" focusable="false"><path d="M0,70 C260,20 520,120 780,74 C1040,28 1240,60 1440,40 L1440,130 L0,130 Z"></path></svg>
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-to/62" viewBox="0 0 1440 130" preserveAspectRatio="none" focusable="false"><path d="M0,86 C240,44 500,126 760,88 C1020,50 1250,96 1440,66 L1440,130 L0,130 Z"></path></svg>
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-to" viewBox="0 0 1440 130" preserveAspectRatio="none" focusable="false"><path d="M0,100 C220,70 480,132 740,102 C1000,72 1250,120 1440,92 L1440,130 L0,130 Z"></path></svg>
</div>
</div>
<div class="bg-twd04-to text-twd04-toink px-6 pt-8 pb-16 text-center">
<p class="text-[15px]">Back layers are stepped tints of one hue; only the front layer is opaque.</p>
</div>
<!-- Duotone offset ribbons -->
<div class="relative overflow-hidden bg-twd04-navy text-white px-6 pt-17 pb-29 text-center">
<h2 class="text-[clamp(25px,4vw,38px)] font-semibold">Two-colour ribbon seam</h2>
<div aria-hidden="true" class="absolute inset-x-0 -bottom-px h-[clamp(64px,10vw,120px)] pointer-events-none">
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-accent" viewBox="0 0 1440 120" preserveAspectRatio="none" focusable="false"><path d="M0,54 C300,110 620,6 940,52 C1160,84 1300,92 1440,62 L1440,120 L0,120 Z"></path></svg>
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-shell" viewBox="0 0 1440 120" preserveAspectRatio="none" focusable="false"><path d="M0,74 C300,126 620,22 940,70 C1160,102 1300,110 1440,80 L1440,120 L0,120 Z"></path></svg>
</div>
</div>
<div class="bg-twd04-shell text-twd04-navyink px-6 pt-8 pb-15 text-center">
<p class="text-[15px] max-w-[52ch] mx-auto">An accent ribbon peeks out from under the opaque edge — brand colour, no extra markup weight.</p>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-twd04-from: #443a77;
--color-twd04-from: oklch(0.34 0.12 285);
--color-twd04-to: #eeeaf7;
--color-twd04-to: oklch(0.95 0.03 285);
--color-twd04-toink: #4a4173;
--color-twd04-toink: oklch(0.4 0.09 285);
--color-twd04-navy: #17323c;
--color-twd04-navy: oklch(0.24 0.04 200);
--color-twd04-navyink: #2b4b57;
--color-twd04-navyink: oklch(0.38 0.05 200);
--color-twd04-shell: #f6f9fa;
--color-twd04-shell: oklch(0.97 0.01 200);
--color-twd04-accent: #e0a92c;
--color-twd04-accent: oklch(0.75 0.17 88);
--font-twd04-sans: 'Space Grotesk', system-ui, sans-serif;
}
.twd-04 {
width: 100%;
min-height: 100svh;
}
```Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Stacked Multi Color SVG Wave Section Divider
Source: https://codefronts.com/layouts/tailwind-css-wave-section-dividers/tailwind-stacked-multi-color-svg-wave-section-divider/
Two or three offset waves in tinted layers, so a change of background colour reads as depth instead of a line. The port replaces a ladder of :nth-child() + color-mix() rules with an opacity modifier on each layer’s own fill-* utility.
## HTML
```html
<section class="twd-04 w-full min-h-svh flex flex-col font-twd04-sans">
<!-- Three tinted layers -->
<div class="relative overflow-hidden bg-twd04-from text-white px-6 pt-18 pb-32 text-center">
<h2 class="text-[clamp(25px,4vw,38px)] font-semibold">Layered depth, one hue</h2>
<div aria-hidden="true" class="absolute inset-x-0 -bottom-px h-[clamp(70px,11vw,130px)] pointer-events-none">
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-to/30" viewBox="0 0 1440 130" preserveAspectRatio="none" focusable="false"><path d="M0,70 C260,20 520,120 780,74 C1040,28 1240,60 1440,40 L1440,130 L0,130 Z"></path></svg>
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-to/62" viewBox="0 0 1440 130" preserveAspectRatio="none" focusable="false"><path d="M0,86 C240,44 500,126 760,88 C1020,50 1250,96 1440,66 L1440,130 L0,130 Z"></path></svg>
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-to" viewBox="0 0 1440 130" preserveAspectRatio="none" focusable="false"><path d="M0,100 C220,70 480,132 740,102 C1000,72 1250,120 1440,92 L1440,130 L0,130 Z"></path></svg>
</div>
</div>
<div class="bg-twd04-to text-twd04-toink px-6 pt-8 pb-16 text-center">
<p class="text-[15px]">Back layers are stepped tints of one hue; only the front layer is opaque.</p>
</div>
<!-- Duotone offset ribbons -->
<div class="relative overflow-hidden bg-twd04-navy text-white px-6 pt-17 pb-29 text-center">
<h2 class="text-[clamp(25px,4vw,38px)] font-semibold">Two-colour ribbon seam</h2>
<div aria-hidden="true" class="absolute inset-x-0 -bottom-px h-[clamp(64px,10vw,120px)] pointer-events-none">
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-accent" viewBox="0 0 1440 120" preserveAspectRatio="none" focusable="false"><path d="M0,54 C300,110 620,6 940,52 C1160,84 1300,92 1440,62 L1440,120 L0,120 Z"></path></svg>
<svg class="absolute inset-x-0 bottom-0 block w-full h-full fill-twd04-shell" viewBox="0 0 1440 120" preserveAspectRatio="none" focusable="false"><path d="M0,74 C300,126 620,22 940,70 C1160,102 1300,110 1440,80 L1440,120 L0,120 Z"></path></svg>
</div>
</div>
<div class="bg-twd04-shell text-twd04-navyink px-6 pt-8 pb-15 text-center">
<p class="text-[15px] max-w-[52ch] mx-auto">An accent ribbon peeks out from under the opaque edge — brand colour, no extra markup weight.</p>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-twd04-from: #443a77;
--color-twd04-from: oklch(0.34 0.12 285);
--color-twd04-to: #eeeaf7;
--color-twd04-to: oklch(0.95 0.03 285);
--color-twd04-toink: #4a4173;
--color-twd04-toink: oklch(0.4 0.09 285);
--color-twd04-navy: #17323c;
--color-twd04-navy: oklch(0.24 0.04 200);
--color-twd04-navyink: #2b4b57;
--color-twd04-navyink: oklch(0.38 0.05 200);
--color-twd04-shell: #f6f9fa;
--color-twd04-shell: oklch(0.97 0.01 200);
--color-twd04-accent: #e0a92c;
--color-twd04-accent: oklch(0.75 0.17 88);
--font-twd04-sans: 'Space Grotesk', system-ui, sans-serif;
}
.twd-04 {
width: 100%;
min-height: 100svh;
}
```How this works
Each layer is its own absolutely positioned SVG in the same stacking container, filled with a stepped opacity of the destination colour. Because every tint is the same hue, the stack stays harmonious rather than looking like three unrelated ribbons.
<svg class="absolute inset-0 fill-twd04-to/30">…
<svg class="absolute inset-0 fill-twd04-to/62">…
<svg class="absolute inset-0 fill-twd04-to">… <!-- opaque, last, joins the next section -->Only the last layer is opaque, and it is the one that actually meets the next section, so the seam is solid no matter how the tints resolve. The duotone variant is the same idea with two layers and a 20px offset, so only a sliver of brand colour shows.
Make it yours
- Two layers for restraint, three for a brochure feel; past four it turns to mush.
- Shift each layer with
bottom-1.5…bottom-3.5to control how much peeks out. - Use different paths per layer rather than one path offset — identical paths read mechanical.
- Retint by editing
--color-twd04-toonly; every modifier follows.
Gotchas — read before shipping
- The topmost layer must be fully opaque, or the previous section shows through the seam.
- Let DOM order do the stacking. Adding
z-indexto absolute siblings inside one container is how these stacks start fighting. - Step one hue. Mixing unrelated hues at 30% and 62% produces mud, not depth.
- Every layer needs
pointer-events-none— three stacked layers over a CTA is three chances to eat the click. fill-*/62is an alpha on the paint, not anopacityon the element: do not reach foropacity-60, which would also fade a stroke or a filter.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Tailwind's opacity modifiers compile to color-mix(), which is exactly what the CSS original wrote by hand — so the support floor is unchanged from the hand-written version.