Build a Curvaceous Homepage // Wavy Background Tutorial with SVG & CSS
Based on Fireship's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.
Use VS Code Emmet snippets to generate repeated section markup quickly, then style each `section` as a centered flex container.
Briefing
A curvy, wave-filled homepage can be built without starting from scratch—by combining CSS-only shapes, SVG “spacer” backgrounds, and a JavaScript-driven morphing blob. The payoff is a design that turns flat section breaks into smooth, attention-grabbing transitions, while staying beginner-friendly through practical tooling and copy-pasteable snippets.
The build starts with a simple HTML page: a hero section at the top, multiple content sections in the middle, and a footer at the bottom. To speed up markup, the workflow uses VS Code Emmet snippets (like `section*8`) to generate repeated section blocks containing headings and paragraphs. For local preview, the tutorial recommends running `npx serve` to view the page at `localhost:5000`.
Styling establishes the baseline look: margin reset, a Google Fonts typeface, light text on a dark background, and a flexbox layout that centers content within each section. Each `section` is set to `position: relative` so decorative elements can be absolutely positioned inside it. With consistent spacing—minimum height, top/bottom padding, and responsive left/right padding using viewport width units—the page becomes a clean canvas for curves.
The first curve technique uses pure CSS. An empty `div` acts as a container for a “curve” layer positioned at the bottom of its parent section. The curve is created by stacking `::before` and `::after` pseudo-elements shaped as ellipses via `border-radius` with two values (vertical and horizontal radii). Careful placement with `transform: translate(...)` aligns the overlapping ellipses to sell the illusion of a continuous wave. Because this approach can cause horizontal overflow, the parent can set `overflow-x: hidden` to prevent unwanted scrollbars.
For simpler, more scalable separators, the tutorial shifts to SVG. It uses free web tools to generate wave SVGs automatically: one tool (Shape Divider) outputs an SVG snippet and matching CSS, while another (High) can generate layered wave backgrounds with adjustable colors and an important aspect ratio—treated like a long, skinny divider. The downloaded SVG is then applied as a background image through a reusable CSS class that leverages the `aspect-ratio` property, ensuring the spacer scales correctly. Empty `div` elements with these classes become the transition graphics between sections.
The final flourish brings motion. Using SVG morphing, the tutorial generates two blob shapes (downloaded as raw SVG) and extracts the relevant `path`/group elements. Each blob path gets an ID (`blob one` and `blob two`), and a small JavaScript setup uses a library called CuteJS (loaded via CDN) to animate between the two shapes. The second blob starts hidden, then the morph runs with a specified duration (3,000ms) and a “yo-yo” back-and-forth effect. The result is a homepage where section transitions feel alive—static curves, SVG wave dividers, and a continuously morphing centerpiece blob—without requiring advanced graphics tooling beyond the provided generators.
Cornell Notes
The homepage becomes “curvaceous” by layering three techniques: CSS ellipses, SVG wave dividers, and an animated SVG blob morph. CSS curves are built by stacking `::before` and `::after` pseudo-elements with elliptical `border-radius`, then aligning them using `transform: translate(...)` inside a `position: relative` section. SVG separators are generated with tools (Shape Divider and High), downloaded as SVG, and applied via CSS background images using the `aspect-ratio` property for consistent scaling. For motion, two blob paths extracted from raw SVG are morphed with CuteJS, using IDs like `blob one` and `blob two`, a 3,000ms duration, and a yo-yo animation that reverses back and forth.
How does the CSS-only curve technique create a wave-like shape without an SVG?
Why set `position: relative` on each `section`?
What makes SVG wave dividers easier to scale than hand-tuned CSS curves?
How does the tutorial animate a morphing blob between two SVG shapes?
What role do the “spacer layers” play in the final layout?
Review Questions
- When building a CSS curve from pseudo-elements, which properties control the ellipse shape and which property is used to align the overlap?
- Why is the `aspect-ratio` property useful when applying an SVG as a background separator?
- What IDs and options are needed to morph between two SVG blob shapes using CuteJS?
Key Points
- 1
Use VS Code Emmet snippets to generate repeated section markup quickly, then style each `section` as a centered flex container.
- 2
Set `position: relative` on each `section` so decorative curves and spacers can be absolutely positioned in the correct local area.
- 3
Create CSS waves by overlapping `::before` and `::after` ellipses using elliptical `border-radius`, then fine-tune alignment with `transform: translate(...)`.
- 4
Prevent layout issues from CSS overlaps by applying `overflow-x: hidden` to the relevant parent container.
- 5
Generate SVG wave dividers with tools, download the SVG, and apply it as a background using CSS `aspect-ratio` for consistent scaling.
- 6
For motion, extract two blob paths from raw SVG, assign IDs, and morph them with CuteJS using a 3,000ms duration and yo-yo reversal.