CSS Tutorial
CSS Website Layout
Most websites share the same skeleton: a header on top, a navigation bar, a main content area with a sidebar, and a footer at the bottom. This tutorial assembles that classic layout step by step using modern CSS - flexbox and grid - and finishes with a complete, responsive page you can run and edit.
The Anatomy of a Web Page
A typical page is built from a handful of full-width or side-by-side regions. Using semantic HTML5 elements for each region makes the structure clear to browsers, search engines, and assistive technology alike.
| Region | Semantic element | Purpose |
|---|---|---|
| Header | <header> | Logo, site title, top banner |
| Navigation | <nav> | Primary menu links |
| Main content | <main> | The page's core content |
| Sidebar | <aside> | Related links, ads, filters |
| Footer | <footer> | Copyright, secondary links |
Step 1: The Header and Nav
Start from the top. The header is a full-width band, and the nav below it is a horizontal flex bar. These stack naturally because they are block elements.
.header { background: #0f766e; color: #fff; padding: 20px; text-align: center; }
.nav { display: flex; background: #134e4a; }
.nav a { color: #fff; padding: 12px 18px; text-decoration: none; }Step 2: Content Beside a Sidebar
The middle of the page places the main content and sidebar side by side. Flexbox makes this easy: set the row as a flex container, let the main content grow to fill space with flex: 1, and give the sidebar a fixed share. Wrapping on small screens keeps it responsive.
.row { display: flex; flex-wrap: wrap; }
.main { flex: 3; padding: 20px; min-width: 250px; }
.sidebar { flex: 1; background: #f1f5f9; padding: 20px; min-width: 180px; }Complete Responsive Layout
Here is the whole page assembled: header, nav, a content-plus-sidebar row, and a footer. Because the row uses flex-wrap, the sidebar drops below the content when the frame gets narrow - resize it to see the responsive behavior.
<!DOCTYPE html>
<html>
<head>
<style>
* { box-sizing: border-box; }
body { margin: 0; font-family: system-ui, sans-serif; }
.header { background: #0f766e; color: #fff; padding: 24px; text-align: center; }
.header h1 { margin: 0; }
.nav { display: flex; background: #134e4a; flex-wrap: wrap; }
.nav a { color: #fff; padding: 14px 18px; text-decoration: none; }
.nav a:hover { background: #0d5f59; }
.row { display: flex; flex-wrap: wrap; }
.main { flex: 3; padding: 20px; min-width: 240px; }
.sidebar { flex: 1; background: #f1f5f9; padding: 20px; min-width: 180px; }
.sidebar h3 { margin-top: 0; }
.footer { background: #1e293b; color: #cbd5e1; text-align: center; padding: 18px; }
</style>
</head>
<body>
<header class="header"><h1>My Website</h1></header>
<nav class="nav">
<a href="#">Home</a>
<a href="#">Jobs</a>
<a href="#">About</a>
<a href="#">Contact</a>
</nav>
<div class="row">
<main class="main">
<h2>Welcome</h2>
<p>This is the main content area. It grows to fill the available space thanks to flex: 3, while the sidebar takes a smaller share.</p>
<p>Resize the frame to watch the sidebar drop below the content on narrow screens.</p>
</main>
<aside class="sidebar">
<h3>Sidebar</h3>
<p>Related links, filters, or ads live here.</p>
</aside>
</div>
<footer class="footer">© 2026 My Website. All rights reserved.</footer>
</body>
</html>flex-wrap: wrap on the row is what makes this layout responsive without a single media query - once the columns cannot fit their min-width, the sidebar wraps to a new line automatically.
The Same Layout with CSS Grid
CSS Grid can express the same page in a very readable way using named template areas. You draw the layout as text, then assign each region to its area - the structure is obvious at a glance.
<!DOCTYPE html>
<html>
<head>
<style>
* { box-sizing: border-box; }
body { margin: 0; font-family: system-ui, sans-serif; }
.page { display: grid; grid-template-areas: "header header" "nav nav" "main side" "footer footer"; grid-template-columns: 3fr 1fr; }
.h { grid-area: header; background: #0f766e; color: #fff; padding: 20px; text-align: center; }
.n { grid-area: nav; background: #134e4a; color: #fff; padding: 12px 20px; }
.m { grid-area: main; padding: 20px; }
.s { grid-area: side; background: #f1f5f9; padding: 20px; }
.f { grid-area: footer; background: #1e293b; color: #cbd5e1; text-align: center; padding: 16px; }
</style>
</head>
<body>
<div class="page">
<div class="h">Header</div>
<div class="n">Navigation</div>
<div class="m">Main content area</div>
<div class="s">Sidebar</div>
<div class="f">Footer</div>
</div>
</body>
</html>Add box-sizing: border-box (usually on * ) when building layouts, so padding is included inside an element's declared width. Without it, padding adds to the width and columns overflow their container.
Key points
- Use semantic elements: header, nav, main, aside, and footer for each region.
- Full-width bands (header, nav, footer) stack naturally as block elements.
- Flexbox with flex: 3 and flex: 1 splits content and sidebar into proportional columns.
- flex-wrap: wrap makes the layout responsive with no media queries.
- CSS Grid template areas offer a highly readable way to describe the whole page.
- Apply box-sizing: border-box so padding does not break your column widths.
