Page Layout Techniques
Layout means deciding where each region of a page sits: the header at the top, a menu beside or above the content, a sidebar, a footer. On a phone those regions usually stack in one column; on a wide screen they spread out side by side.
In this lesson you will build layouts the modern way, with HTML for the regions and CSS Grid and Flexbox for the arrangement. Then you will meet the older techniques, table layouts, frames and floats, that you will still find in old websites, emails and exam papers, and learn why they were replaced.
The modern approach in two steps
Modern layout splits the work cleanly:
- HTML marks the regions with semantic elements:
<header>,<nav>,<main>,<aside>and<footer>. You learnt these in Semantic HTML. Write them in a sensible reading order, because that is the order screen readers, keyboard users and search engines follow. - CSS places the regions. CSS Grid arranges the big page areas in rows and columns, and Flexbox lines up smaller groups, such as the links in a menu or a row of cards.
Because the arrangement lives in CSS, the same HTML can be one column on a phone and three columns on a laptop. You change a few lines of CSS, never the HTML.
Arranging the page with CSS Grid
Grid lets you name areas and then draw the layout as a small text picture with grid-template-areas. Run this example, then make the result window wider and narrower.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Grid page layout</title>
<style>
body { margin: 0; font-family: Arial, sans-serif; }
header, nav, main, aside, footer { padding: 12px; }
header { background: #1e3a5f; color: white; }
nav { background: #dbe7f3; }
main { background: white; }
aside { background: #fff3c4; }
footer { background: #333; color: white; }
/* Phones first: one column, in source order */
.page {
display: grid;
grid-template-areas: "header" "nav" "main" "aside" "footer";
min-height: 100dvh;
grid-template-rows: auto auto 1fr auto auto;
}
header { grid-area: header; }
nav { grid-area: nav; }
main { grid-area: main; }
aside { grid-area: aside; }
footer { grid-area: footer; }
/* Wider screens: menu on the left, sidebar on the right */
@media (min-width: 700px) {
.page {
grid-template-columns: 180px 1fr 220px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
}
}
</style>
</head>
<body>
<div class="page">
<header><strong>Kochi Book Club</strong></header>
<nav>Home<br>Monthly picks<br>Meet-ups<br>Join</nav>
<main>
<h1>November pick</h1>
<p>This month Ananya chose a Malayalam novel in translation. We meet on the last Sunday at the city library.</p>
</main>
<aside><h2>Next meet-up</h2><p>30 November, 5 pm</p></aside>
<footer>Kochi Book Club, Kerala</footer>
</div>
</body>
</html>The HTML never changes. On a narrow screen the five regions stack. Above 700 pixels wide, the media query redraws the picture: the header and footer span all three columns, and the menu, content and sidebar sit side by side. 1fr means "one share of the remaining space", and min-height: 100dvh makes the page at least as tall as the screen, so the footer stays at the bottom of short pages.
This "start with phones, then add rules for bigger screens" habit is called mobile-first design. You will learn Grid properly in CSS Grid Basics and Grid Placement & Areas, and media queries in Responsive Design & Media Queries.
Flexbox for rows of things
Grid is built for two dimensions, rows and columns together. Flexbox is built for one dimension: a single row or column of items that share space. It is perfect for a header with a logo on one side and links on the other.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Flexbox header and cards</title>
<style>
body { margin: 0; font-family: Arial, sans-serif; }
.site-header {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
gap: 8px;
padding: 12px 16px;
background: #7a1f1f;
color: white;
}
.site-header ul { display: flex; gap: 16px; list-style: none; margin: 0; padding: 0; }
.site-header a { color: white; }
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 12px;
padding: 16px;
}
.cards article { border: 1px solid #ccc; border-radius: 8px; padding: 12px; }
</style>
</head>
<body>
<header class="site-header">
<strong>Rasoi Tiffin, Pune</strong>
<nav aria-label="Main">
<ul>
<li><a href="#menu">Menu</a></li>
<li><a href="#plans">Plans</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
</header>
<main class="cards" id="plans">
<article><h2>Daily</h2><p>Lunch only, ₹120 a day.</p></article>
<article><h2>Weekly</h2><p>Lunch and dinner, ₹1,299 a week.</p></article>
<article><h2>Monthly</h2><p>All meals, ₹4,999 a month.</p></article>
</main>
</body>
</html>The header uses Flexbox to push the name and the menu apart. The cards use a Grid trick: repeat(auto-fit, minmax(200px, 1fr)) fits as many 200-pixel-or-wider columns as the screen allows, with no media query at all. Narrow the window and the cards drop to two columns, then one. See Flexbox Basics for the full story.
Some other modern tools you will use with these:
| Need | Tool | Learn it in |
|---|---|---|
| Centre content and limit line length | max-width with margin-inline: auto | Sizing, Aspect Ratio & Overflow |
| A header that stays on screen while scrolling | position: sticky | Positioning |
| Text flowing in newspaper columns | columns | Multi-column Layout |
| A component that adapts to its own width | Container queries | Container Queries |
Legacy layout techniques
Everything in this section is old. Do not use these methods for new web pages. You need to recognise them because millions of existing pages, many company intranets and almost all HTML emails still use them, and older textbooks still teach them.
Table layouts
Before CSS was reliable, around the late 1990s and early 2000s, designers built whole pages out of invisible tables. Each region was a table cell, and tables were nested inside tables.
<!-- OLD: a page laid out with a table. Do not copy. -->
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td colspan="2" bgcolor="#1e3a5f"><font color="white">Kochi Book Club</font></td>
</tr>
<tr>
<td width="180" valign="top">Home<br>Monthly picks</td>
<td valign="top">November pick...</td>
</tr>
</table>Why it was replaced:
- A table tells screen readers "this is data in rows and columns", so they announce a grid that does not exist.
- Table cells cannot rearrange themselves for a phone screen.
- Every page repeats heavy, nested markup, and changing the design means editing every page.
- Attributes like
bgcolor,widthandvalignmix design into the HTML, and most are obsolete.
Tables are still correct for real data, as you will see in HTML Tables. Table layouts also survive in HTML Emails, where many email apps still handle modern CSS poorly.
Frames and framesets
In HTML 4, a <frameset> page replaced the <body> and split the browser window into separate frames, each loading its own HTML file. Sites used it to keep a menu fixed on the left while the content changed on the right.
<!-- OLD: obsolete since HTML5. Do not copy. -->
<frameset cols="200,*">
<frame src="menu.html" name="menu">
<frame src="welcome.html" name="content">
<noframes>Your browser does not support frames.</noframes>
</frameset>Frames caused many problems. The address bar showed only the outer page, so visitors could not bookmark or share a particular page. The Back button behaved strangely, search engines sent people to lone content pages without the menu, and screen reader users struggled to move between frames. The <frameset>, <frame> and <noframes> elements are obsolete. Today a shared menu is added to every page by a template or a server-side include, such as PHP's include (see include & require), and <iframe> is used only to embed separate content like a map, as explained in Iframes & Embeds.
Float layouts
From the mid-2000s until Flexbox and Grid arrived, most sites built columns with the CSS float property. Floats were designed to let text wrap around an image, so using them for columns needed workarounds.
/* OLD: a two-column float layout */
.sidebar { float: left; width: 25%; }
.content { float: left; width: 75%; }
.row::after { content: ""; display: table; clear: both; } /* the "clearfix" */Floated columns are taken out of the normal flow, so their parent collapses to zero height unless you add a "clearfix" rule like the one above. Equal-height columns, vertical centring and reordering were all painful. CSS Grid has worked in all major browsers since 2017, so floats are now used only for their original job. Float & Clear (Legacy Layout) explains them in detail.
You may also find columns made with display: inline-block, with position: absolute and fixed pixel positions, or with layout classes from older CSS frameworks that were built on floats. They all have the same answer today: Grid for page areas, Flexbox for rows of items.
Common mistakes
- Using
<table>to place page regions. Use semantic elements with Grid or Flexbox. - Wrapping everything in plain
<div>elements. Use<header>,<nav>,<main>,<aside>and<footer>for the main regions. - Fixed pixel widths for the whole page. A 1000-pixel-wide page cannot fit a phone; use flexible units and media queries.
- Forgetting the viewport meta tag. Without it, phones shrink the page instead of using your mobile layout.
- Reordering content only with CSS. Keep the HTML reading order sensible.
Key points
- HTML marks the regions with semantic elements; CSS arranges them.
- CSS Grid is for two-dimensional page layouts;
grid-template-areasdraws the layout by name. - Flexbox lines up items in one row or column, such as menus and toolbars.
- Build mobile-first: one column by default, more columns in media queries.
- Table layouts, framesets and float columns are legacy techniques; recognise them, but do not use them for new pages.
Exercise
Build a page for a Jaipur coaching centre with a header, a navigation menu, a main section about courses, an aside with the batch timings and a footer. On phones the regions should stack in that order. From 800 pixels wide, use grid-template-areas to place the menu as a row under the header, and the main section and aside side by side, with the aside narrower. Use Flexbox for the menu links.
Show solution
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Jaipur Coaching Centre</title>
<style>
body { margin: 0; font-family: Arial, sans-serif; }
.page { display: grid; gap: 8px; grid-template-areas: "header" "nav" "main" "aside" "footer"; }
header { grid-area: header; } nav { grid-area: nav; } main { grid-area: main; }
aside { grid-area: aside; } footer { grid-area: footer; }
nav ul { display: flex; flex-wrap: wrap; gap: 16px; list-style: none; padding: 0; }
@media (min-width: 800px) {
.page {
grid-template-columns: 2fr 1fr;
grid-template-areas: "header header" "nav nav" "main aside" "footer footer";
}
}
</style>
</head>
<body>
<div class="page">
<header><h1>Jaipur Coaching Centre</h1></header>
<nav aria-label="Main"><ul><li><a href="#">Courses</a></li><li><a href="#">Results</a></li><li><a href="#">Contact</a></li></ul></nav>
<main><h2>Courses</h2><p>Class 11 and 12 science, and engineering entrance preparation.</p></main>
<aside><h2>Batch timings</h2><p>Morning 7 am, evening 5 pm.</p></aside>
<footer>Malviya Nagar, Jaipur</footer>
</div>
</body>
</html>The HTML is in reading order, and only the media query changes the grid picture. 2fr 1fr makes the main column twice as wide as the aside.
Quick Quiz
1. Which is the modern way to place a header, sidebar, content area and footer?
Semantic elements describe the regions, and Grid arranges them without changing the HTML.
2. When is Flexbox usually a better fit than Grid?
Flexbox handles one dimension, such as a row of items; Grid handles rows and columns together.
3. Why were frameset layouts abandoned?
The address bar showed only the outer frameset page, which broke bookmarks, sharing and navigation.
4. Where are table-based layouts still common today?
Many email apps still support modern CSS poorly, so email designers still use tables.
Learn HTML with a mentor
Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
