CSS Tutorial
CSS Project: Magazine Layout
A two-column magazine page: a featured story, a sidebar list, and a footer using grid areas.
What you will build
One issue of Harbor Review, the studio magazine. A masthead, a featured story, a sidebar of shorter notes, and a footer. Grid template areas name those regions so the layout reads like a printed spread: story on the left, list on the right, footer full width.
Type does as much work as the grid. The feature uses a large serif headline. The sidebar stays smaller and tighter. A media query stacks the spread on a phone so the sidebar follows the story instead of squeezing beside it.
Open an example with Try it in CSS. That loads /css/try — a live page preview.
Properties you will use
| Property | Job on this page |
|---|---|
grid-template-areas | Names masthead, feature, rail, and footer |
grid-area | Places each region in the named cell |
serif / sans font-family | Separates the story voice from the masthead chrome |
line-height and measure | Keeps the feature readable |
@media | Restacks areas into a single column |
Name the areas in quotes, then assign them. If you only use column numbers, the layout still works — it is harder to read six months later.
Build in slices
First declare the areas. Four children, four names. On a wide window the feature and rail share a row.
Example
<style>
body { margin: 0; background: #e0f2fe; color: #0c4a6e; font-family: Georgia, serif; }
.issue {
display: grid;
grid-template-columns: 1fr 16rem;
grid-template-areas:
"mast mast"
"feature rail"
"foot foot";
gap: 1.1rem;
max-width: 56rem;
margin: 0 auto;
padding: 1.25rem;
}
.mast { grid-area: mast; }
.feature { grid-area: feature; }
.rail { grid-area: rail; }
.foot { grid-area: foot; }
</style>
<div class="issue">
<header class="mast"><p>Harbor Review · Spring</p></header>
<article class="feature"><h1>The window table</h1></article>
<aside class="rail"><h2>Also in this issue</h2></aside>
<footer class="foot"><p>Printed at Harbor studio.</p></footer>
</div>Then set type and the stacked query. The feature headline is large. The rail list is compact. Under 44 rem every area is one column.
Example
<style>
.mast {
font-family: system-ui, sans-serif;
letter-spacing: 0.12em;
text-transform: uppercase;
font-size: 0.8rem;
font-weight: 700;
color: #0284c7;
}
.feature h1 {
font-size: clamp(1.8rem, 4vw, 2.6rem);
line-height: 1.15;
margin: 0 0 0.7rem;
}
.feature p { line-height: 1.55; max-width: 42rem; }
@media (max-width: 44rem) {
.issue {
grid-template-columns: 1fr;
grid-template-areas:
"mast"
"feature"
"rail"
"foot";
}
}
</style>Resize the preview at /css/try. The rail should drop under the story, not sit as a squeezed third of the page.
Complete page
A full Harbor Review spread you can keep. The story is original copy. The sidebar lists three notes. The footer names the studio. This is the last CSS project — when you have changed the areas, open the examples shelf for smaller snippets.
Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Harbor Review — spring issue</title>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
background: #e0f2fe;
color: #0c4a6e;
font-family: Georgia, "Times New Roman", serif;
}
.issue {
display: grid;
grid-template-columns: minmax(0, 1fr) 16.5rem;
grid-template-areas:
"mast mast"
"feature rail"
"foot foot";
gap: 1.15rem 1.4rem;
max-width: 58rem;
margin: 0 auto;
padding: 1.5rem 1.25rem 2rem;
}
.mast { grid-area: mast; }
.feature { grid-area: feature; }
.rail { grid-area: rail; }
.foot { grid-area: foot; }
.mast {
display: flex;
justify-content: space-between;
align-items: baseline;
gap: 0.75rem;
border-bottom: 3px solid #0284c7;
padding-bottom: 0.55rem;
font-family: system-ui, sans-serif;
letter-spacing: 0.12em;
text-transform: uppercase;
font-size: 0.78rem;
font-weight: 800;
color: #0284c7;
}
.feature {
background: #fff;
border-radius: 1rem;
padding: 1.35rem 1.3rem 1.5rem;
box-shadow: 0 12px 26px rgba(12, 74, 110, 0.1);
}
.kicker {
margin: 0 0 0.35rem;
font-family: system-ui, sans-serif;
font-size: 0.75rem;
letter-spacing: 0.08em;
text-transform: uppercase;
color: #0284c7;
font-weight: 700;
}
.feature h1 {
margin: 0 0 0.75rem;
font-size: clamp(1.85rem, 4vw, 2.65rem);
line-height: 1.12;
}
.feature p {
margin: 0 0 0.85rem;
line-height: 1.55;
max-width: 42rem;
}
.feature p:last-child { margin-bottom: 0; }
.rail {
background: #fff;
border-radius: 1rem;
padding: 1.1rem 1.15rem 1.2rem;
box-shadow: 0 12px 26px rgba(12, 74, 110, 0.1);
}
.rail h2 {
margin: 0 0 0.7rem;
font-family: system-ui, sans-serif;
font-size: 0.82rem;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.rail ol {
margin: 0;
padding: 0;
list-style: none;
}
.rail li {
padding: 0.65rem 0;
border-top: 1px solid #bae6fd;
}
.rail li:first-child { border-top: 0; padding-top: 0; }
.rail strong { display: block; }
.rail span { color: #075985; font-size: 0.92rem; }
.foot {
font-family: system-ui, sans-serif;
font-size: 0.88rem;
color: #075985;
border-top: 1px solid #7dd3fc;
padding-top: 0.7rem;
}
.foot p { margin: 0; }
@media (max-width: 44rem) {
.issue {
grid-template-columns: 1fr;
grid-template-areas:
"mast"
"feature"
"rail"
"foot";
}
}
</style>
</head>
<body>
<div class="issue">
<header class="mast">
<p>Harbor Review</p>
<p>Spring issue</p>
</header>
<article class="feature">
<p class="kicker">Feature</p>
<h1>The window table still faces the pier</h1>
<p>
Harbor studio kept the chart-room window when the cafe opened the shared door. The table is not a
decoration. Proofs land there at 8:10. Sourdough cools on the other side of the glass.
</p>
<p>
Lena Voss sets type while the first espresso cools. Menus go on the line by noon. If the sitting at 9:30
is full, the board says so in the same navy we use on every card.
</p>
<p>
Visitors still ask whether this is a press or a kitchen. The honest answer is both, and the grid on this
page is how the magazine says it: one story, a short rail, a footer that names the shop.
</p>
</article>
<aside class="rail">
<h2>Also in this issue</h2>
<ol>
<li>
<strong>Olive oil, again</strong>
<span>Why the cafe board never drops the third item.</span>
</li>
<li>
<strong>Workshop hours</strong>
<span>Weekday, Harbor, and Season seats for the quarter.</span>
</li>
<li>
<strong>Pier 2 after rain</strong>
<span>A note on wet boots and the studio mat.</span>
</li>
</ol>
</aside>
<footer class="foot">
<p>Printed at Harbor studio · Open 8–16 · Chart Room, Pier 2</p>
</footer>
</div>
</body>
</html>Practice tasks
- Swap the feature and rail in
grid-template-areasso the list sits on the left. Keep the masthead and footer full width. - Rewrite the feature for a winter issue. Keep the same regions and the serif headline.
- Raise the rail width to
20remand check the measure of the story at /css/try.
Next, browse smaller patterns on CSS Examples. The projects taught full pages. The examples shelf is for one property at a time.