The reading column
The post page itself. One narrow column (~60–75 characters wide), a big serif headline, clear byline, and roomy line spacing. Nothing competes with the words.
Why whitespace is the best tool you're not using
Good typography isn't about fancy fonts — it's about giving words room to breathe. A measure of 60 to 75 characters keeps the eye from getting lost on the way back to the next line.
The space between your words matters as much as the words themselves.
Set a comfortable line height (around 1.7), keep your column narrow, and resist the urge to fill every pixel.
line-height is the single biggest readability win. Capping width with max-width stops lines from getting fatiguingly long on wide screens.<article class="post"> <span class="cat">Design</span> <h1>Why whitespace is the best tool you're not using</h1> <p class="meta">By Maya Chen · May 29, 2026 · 6 min read</p> <p>Good typography isn't about fancy fonts — it's about giving words room to breathe. A measure of 60 to 75 characters keeps the eye from getting lost on the way back to the next line.</p> <blockquote>The space between your words matters as much as the words themselves.</blockquote> <p>Set a comfortable line height (around 1.7), keep your column narrow, and resist the urge to fill every pixel.</p> </article>
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #fff; color: #1d1d1f; margin: 0; }
.post { max-width: 65ch; margin: 40px auto; padding: 0 20px; } /* the key: cap the width */
.post .cat { color: #b45309; font-weight: 700; text-transform: uppercase; font-size: .68rem; letter-spacing: .08em; }
.post h1 { font-family: Georgia, serif; font-size: 2rem; line-height: 1.2; margin: 8px 0 6px; }
.post .meta { color: #6b7280; font-size: .82rem; border-bottom: 1px solid #eee; padding-bottom: 14px; margin-bottom: 14px; }
.post p { color: #374151; font-size: 1.05rem; line-height: 1.7; margin-bottom: 12px; } /* roomy reading */
.post blockquote {
border-left: 3px solid #f59e0b;
padding-left: 16px; margin: 14px 0;
font-family: Georgia, serif; font-style: italic; font-size: 1.3rem; color: #1d1d1f;
}
Featured post + list
A blog home page: one hero story takes the spotlight while recent posts stack beside it. Instantly tells readers "start here."
Building a design system from scratch
A six-part series on tokens, components, and docs.
Writing better alt text
4 min readPicking an accessible palette
7 min readShip your first site free
5 min read<div class="home">
<article class="featured">
<!-- gradient box stands in for a photo; swap for <img> when you have one -->
<div class="img"></div>
<div class="bd">
<span class="cat">Featured</span>
<h2>Building a design system from scratch</h2>
<p>A six-part series on tokens, components, and docs.</p>
</div>
</article>
<aside class="recent">
<a class="mini"><div class="thumb"></div><div><h3>Writing better alt text</h3><small>4 min read</small></div></a>
<a class="mini"><div class="thumb"></div><div><h3>Picking an accessible palette</h3><small>7 min read</small></div></a>
<a class="mini"><div class="thumb"></div><div><h3>Ship your first site free</h3><small>5 min read</small></div></a>
</aside>
</div>
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #fff; color: #1d1d1f; margin: 20px; }
.cat { color: #b45309; font-weight: 700; text-transform: uppercase; font-size: .68rem; letter-spacing: .08em; }
.home { display: grid; grid-template-columns: 1.5fr 1fr; gap: 16px; }
/* featured card */
.featured { border: 1px solid #eee; border-radius: 12px; overflow: hidden; }
.featured .img { aspect-ratio: 16 / 9; background: linear-gradient(135deg, #fde68a, #fca5a5); }
.featured .bd { padding: 16px; }
.featured h2 { font-family: Georgia, serif; font-size: 1.4rem; line-height: 1.2; margin: 6px 0; }
.featured p { color: #6b7280; font-size: .86rem; }
/* recent list */
.recent { display: grid; gap: 12px; }
.mini { display: grid; grid-template-columns: 70px 1fr; gap: 10px; align-items: center; text-decoration: none; color: inherit; }
.mini .thumb { aspect-ratio: 1; border-radius: 8px; background: linear-gradient(135deg, #fde68a, #fca5a5); }
.mini h3 { font-family: Georgia, serif; font-size: .95rem; line-height: 1.25; }
.mini small { color: #9ca3af; font-size: .74rem; }
@media (max-width: 640px) { .home { grid-template-columns: 1fr; } }
Card grid (the index)
The all-posts page: equal cards with a thumbnail, category, title, and a teaser. Responsive and endlessly scannable.
Grid in 5 minutes
Rows, columns, gaps — the essentials.
Designing for thumbs
Why mobile-first still matters.
Subtle, not flashy
Animation that helps, not distracts.
repeat(auto-fill, minmax()) makes the grid reflow on any screen.<div class="grid">
<article class="card">
<!-- gradient box stands in for a photo; swap for <img> when you have one -->
<div class="img"></div>
<div class="body">
<span class="cat">CSS</span>
<h3>Grid in 5 minutes</h3>
<p>Rows, columns, gaps — the essentials.</p>
</div>
</article>
<article class="card">
<div class="img"></div>
<div class="body">
<span class="cat">UX</span>
<h3>Designing for thumbs</h3>
<p>Why mobile-first still matters.</p>
</div>
</article>
<article class="card">
<div class="img"></div>
<div class="body">
<span class="cat">Motion</span>
<h3>Subtle, not flashy</h3>
<p>Animation that helps, not distracts.</p>
</div>
</article>
</div>
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #fff; color: #1d1d1f; margin: 20px; }
.cat { color: #b45309; font-weight: 700; text-transform: uppercase; font-size: .68rem; letter-spacing: .08em; }
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); /* responsive */
gap: 14px;
}
.card { border: 1px solid #eee; border-radius: 12px; overflow: hidden; }
.card .img { width: 100%; aspect-ratio: 16 / 10; background: linear-gradient(135deg, #fde68a, #fca5a5); }
/* using a real photo? swap .img for an <img> and use these instead:
.card img { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; display: block; } */
.card .body { padding: 12px 14px; }
.card h3 { font-family: Georgia, serif; font-size: 1.02rem; line-height: 1.25; margin: 6px 0; }
.card p { color: #6b7280; font-size: .8rem; }
Content + sidebar
The classic blog: a main feed beside a sidebar of categories, search, or recent posts — persistent context as you read.
Your first deploy on Netlify
May 28 · 5 minDebugging CSS like a pro
May 24 · 8 minAccessible forms, simply
May 20 · 6 minposition: sticky so it follows along on long articles.<div class="layout">
<main class="feed">
<article class="row"><div class="thumb"></div><div><span class="cat">Tutorial</span><h3>Your first deploy on Netlify</h3><small>May 28 · 5 min</small></div></article>
<article class="row"><div class="thumb"></div><div><span class="cat">Tips</span><h3>Debugging CSS like a pro</h3><small>May 24 · 8 min</small></div></article>
<article class="row"><div class="thumb"></div><div><span class="cat">Forms</span><h3>Accessible forms, simply</h3><small>May 20 · 6 min</small></div></article>
</main>
<aside class="sidebar">
<h4>Categories</h4>
<div class="tags"><span>CSS</span><span>UX</span><span>JS</span><span>Career</span></div>
<h4>Recent</h4>
<ul><li>Grid in 5 minutes</li><li>Designing for thumbs</li><li>Subtle motion</li></ul>
</aside>
</div>
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #fff; color: #1d1d1f; margin: 20px; }
.cat { color: #b45309; font-weight: 700; text-transform: uppercase; font-size: .68rem; letter-spacing: .08em; }
.layout { display: grid; grid-template-columns: 1fr 220px; gap: 22px; }
/* main feed */
.feed .row { display: flex; gap: 14px; padding: 12px 0; border-bottom: 1px solid #eee; }
.feed .thumb { width: 90px; height: 64px; border-radius: 8px; flex-shrink: 0; background: linear-gradient(135deg, #fde68a, #fca5a5); }
.feed h3 { font-family: Georgia, serif; font-size: 1.05rem; line-height: 1.25; }
.feed small { color: #9ca3af; font-size: .76rem; }
/* sidebar */
.sidebar { position: sticky; top: 20px; align-self: start; background: #f5f5f7; border-radius: 12px; padding: 18px; } /* follows as you scroll */
.sidebar h4 { font-size: .7rem; text-transform: uppercase; letter-spacing: .08em; color: #6b7280; margin-bottom: 10px; }
.tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 16px; }
.tags span { font-size: .74rem; background: #fff; border: 1px solid #e5e7eb; border-radius: 999px; padding: 4px 10px; color: #374151; }
.sidebar ul { list-style: none; display: grid; gap: 8px; padding: 0; }
.sidebar li { font-size: .84rem; color: #374151; }
@media (max-width: 640px) { .layout { grid-template-columns: 1fr; } }
Magazine front page
Editorial energy borrowed from newspapers: a dominant lead story next to a ruled stack of secondary headlines. Great for news-style and high-volume blogs.
The quiet comeback of the personal website
Why makers are leaving the feed and building their own corners of the web again.
Bento grids are everywhere
3 min5 free fonts that look premium
4 minStop animating everything
6 min<div class="magazine">
<article class="lead">
<!-- gradient box stands in for a photo; swap for <img> when you have one -->
<div class="img"></div>
<span class="cat">Cover Story</span>
<h2>The quiet comeback of the personal website</h2>
<p>Why makers are leaving the feed and building their own corners of the web again.</p>
</article>
<div class="more">
<article class="row"><span class="cat">Trends</span><h3>Bento grids are everywhere</h3><small>3 min</small></article>
<article class="row"><span class="cat">Tools</span><h3>5 free fonts that look premium</h3><small>4 min</small></article>
<article class="row"><span class="cat">Opinion</span><h3>Stop animating everything</h3><small>6 min</small></article>
</div>
</div>
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #fff; color: #1d1d1f; margin: 20px; }
.cat { color: #b45309; font-weight: 700; text-transform: uppercase; font-size: .68rem; letter-spacing: .08em; }
.magazine { display: grid; grid-template-columns: 1.7fr 1fr; gap: 16px; }
/* lead story */
.lead .img { aspect-ratio: 16 / 9; border-radius: 10px; background: linear-gradient(135deg, #fde68a, #fca5a5); }
.lead h2 { font-family: Georgia, serif; font-size: 1.6rem; line-height: 1.15; margin: 10px 0 6px; }
.lead p { color: #6b7280; font-size: .86rem; }
/* ruled secondary list */
.more { display: grid; }
.row { padding: 11px 0; border-bottom: 1px solid #eee; } /* ruled list */
.row h3 { font-family: Georgia, serif; font-size: 1rem; line-height: 1.25; }
.row small { color: #9ca3af; font-size: .74rem; }
@media (max-width: 640px) { .magazine { grid-template-columns: 1fr; } }
Minimal post list
When the writing is the star: a clean typographic list of date, title, and reading time. Loads fast, feels confident, ages well.
Why whitespace wins
6 minThe case for boring tech
9 minWriting in public
4 minLess framework, more fundamentals
7 min<ul class="posts">
<li>
<time>May 29</time>
<h3>Why whitespace wins</h3>
<span>6 min</span>
</li>
<li>
<time>May 22</time>
<h3>The case for boring tech</h3>
<span>9 min</span>
</li>
<li>
<time>May 15</time>
<h3>Writing in public</h3>
<span>4 min</span>
</li>
<li>
<time>May 08</time>
<h3>Less framework, more fundamentals</h3>
<span>7 min</span>
</li>
</ul>
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #fff; color: #1d1d1f; margin: 20px; }
.posts { list-style: none; margin: 0; padding: 0; max-width: 640px; }
.posts li {
display: grid;
grid-template-columns: 90px 1fr auto; /* date | title | read time */
gap: 16px; align-items: baseline;
padding: 16px 0; border-top: 1px solid #eee;
}
.posts li:first-child { border-top: 0; }
.posts time { color: #9ca3af; font-size: .78rem; font-weight: 600; }
.posts h3 { font-family: Georgia, serif; font-size: 1.2rem; }
.posts span { color: #9ca3af; font-size: .78rem; white-space: nowrap; }
Putting real photos in the placeholders
Every gradient box above is a stand-in for a real photo. To use your own, replace each <div class="imgph"> with an <img> — the layout doesn't change, because the image takes the exact same size as the placeholder it replaces.
How to do it
- Make an
images/folder next to your HTML file and drop your photos into it. - Replace the placeholder — swap each
<div class="imgph">for<img src="images/my-photo.jpg" alt="...">. Building fast? Paste a hosted URL from Unsplash or Pexels for now. - Let CSS size it — give the image the same
aspect-ratioandborder-radiusas the box, then addobject-fit: coverso any photo fills it without stretching. - Write real
alttext describing the photo. It helps screen-reader users and your SEO. - Optimize first — resize big photos to the size they'll show, compress them, and add
loading="lazy"to images below the fold so posts load fast.
aspect-ratio, and rounded corners as the placeholder, then add object-fit: cover so any photo fills the box neatly without stretching or squishing.<!-- BEFORE: the placeholder -->
<div class="imgph"></div>
<!-- AFTER: drop in a real image -->
<img class="post-img" src="images/my-photo.jpg"
alt="A short description of the photo">
<!-- ...or use a free hosted photo while you build -->
<img class="post-img"
src="https://images.unsplash.com/photo-1517649763962-0c623066013b?w=600&q=70"
alt="Sunlit mountain landscape">
.post-img {
width: 100%;
aspect-ratio: 16 / 9; /* match the placeholder's shape */
object-fit: cover; /* fill the box, crop the overflow */
border-radius: 10px; /* same corners as the placeholder */
display: block;
}
images/ folder next to your HTML and point src at it. Always write real alt text that describes the photo — it helps screen-reader users and SEO. Need sized boxes to test with? See Placeholder Images.The whole thing as one file
A complete blog home page — a featured reading column above a responsive card grid — combined into one standalone HTML file with all the CSS inline. Copy it into a new file called blog.html, open it in a browser, and it just works — no libraries, no build step.
Live preview
Complete HTML — copy this whole file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>The Margin — A Blog About the Web</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, sans-serif;
color: #1d1d1f; background: #fff; line-height: 1.6;
}
.ser { font-family: Georgia, 'Times New Roman', serif; }
.cat { color: #b45309; font-weight: 700; text-transform: uppercase; font-size: .68rem; letter-spacing: .08em; }
/* page chrome */
.masthead { border-bottom: 1px solid #eee; padding: 22px 24px; text-align: center; }
.masthead h1 { font-family: Georgia, serif; font-size: 1.8rem; letter-spacing: -.01em; }
.masthead p { color: #6b7280; font-size: .85rem; margin-top: 4px; }
.wrap { max-width: 960px; margin: 0 auto; padding: 32px 24px 64px; }
/* the reading column (featured post) */
.post { max-width: 65ch; margin: 0 auto 48px; } /* the key: cap the width */
.post h2 { font-family: Georgia, serif; font-size: 2rem; line-height: 1.2; margin: 8px 0 6px; }
.post .meta { color: #6b7280; font-size: .82rem; border-bottom: 1px solid #eee; padding-bottom: 14px; margin-bottom: 14px; }
.post p { font-size: 1.05rem; line-height: 1.8; margin-bottom: 14px; } /* roomy reading */
.post blockquote {
border-left: 3px solid #f59e0b; padding-left: 16px;
font-family: Georgia, serif; font-style: italic; font-size: 1.3rem; margin: 16px 0;
}
/* the card grid (index) */
.section-title { font-family: Georgia, serif; font-size: 1.3rem; margin-bottom: 16px; }
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); /* responsive */
gap: 16px;
}
.card { border: 1px solid #eee; border-radius: 12px; overflow: hidden; }
.card .img {
aspect-ratio: 16 / 10;
background: linear-gradient(135deg, #fde68a, #fca5a5);
display: flex; align-items: center; justify-content: center;
color: #b45309; font-size: 1.6rem;
}
.card .body { padding: 12px 14px; }
.card h3 { font-family: Georgia, serif; font-size: 1.02rem; line-height: 1.25; margin: 6px 0; }
.card p { color: #6b7280; font-size: .8rem; }
footer { text-align: center; padding: 32px 24px; border-top: 1px solid #eee; color: #9ca3af; font-size: .82rem; }
</style>
</head>
<body>
<header class="masthead">
<h1 class="ser">The Margin</h1>
<p>Notes on design, code, and the open web</p>
</header>
<div class="wrap">
<!-- Featured post: the reading column -->
<article class="post">
<span class="cat">Design</span>
<h2>Why whitespace is the best tool you're not using</h2>
<p class="meta">By Maya Chen · May 29, 2026 · 6 min read</p>
<p>Good typography isn't about fancy fonts — it's about giving words room to breathe. A measure of 60 to 75 characters keeps the eye from getting lost on the way back to the next line.</p>
<blockquote>The space between your words matters as much as the words themselves.</blockquote>
<p>Set a comfortable line height (around 1.7), keep your column narrow, and resist the urge to fill every pixel. The result reads calmer and feels more confident.</p>
</article>
<!-- Index: the card grid -->
<h2 class="section-title">More from the blog</h2>
<div class="grid">
<article class="card">
<div class="img">☷</div>
<div class="body">
<span class="cat">CSS</span>
<h3>Grid in 5 minutes</h3>
<p>Rows, columns, gaps — the essentials.</p>
</div>
</article>
<article class="card">
<div class="img">☼</div>
<div class="body">
<span class="cat">UX</span>
<h3>Designing for thumbs</h3>
<p>Why mobile-first still matters.</p>
</div>
</article>
<article class="card">
<div class="img">✦</div>
<div class="body">
<span class="cat">Motion</span>
<h3>Subtle, not flashy</h3>
<p>Animation that helps, not distracts.</p>
</div>
</article>
</div>
</div>
<footer>© 2026 The Margin — built with plain HTML & CSS</footer>
</body>
</html>