These three patterns map directly to page structures you will build in projects. Each is a named, reusable recipe rather than a one-off solution.
Breakpoint note: Pattern 2 (content + sidebar) switches from one column to a 2fr 1fr split at 820px. The playground preview is a fixed-size iframe so this transition will not trigger in the embed — open the standalone file once it is published to see it respond. Pattern 3 (card gallery) uses auto-fit + minmax and responds dynamically to whatever width is available, so it works well in the playground.
What this covers
- Stacked mobile sections: default single-column grid with no media queries needed
- Content + sidebar: starts stacked, expands to
2fr 1fr at 820px
- Card gallery:
repeat(auto-fit, minmax(180px, 1fr)) creates responsive columns without explicit breakpoints
<main class="stack">
<h1>Common Layout Patterns</h1>
<p class="hint">These patterns map directly to page structures you can reuse in your own projects.</p>
<p class="callout">Your goal: use repeatable layout recipes you can apply quickly to real pages.</p>
<section class="card stack">
<h2>Pattern 1: Stacked Mobile Sections</h2>
<ul class="explain-list">
<li>Default stacked flow is often best for phones.</li>
<li>No media query is required for this baseline pattern.</li>
</ul>
<!-- Good default pattern for narrow screens -->
<div class="pattern stacked">
<div class="box">Hero<span class="meta">top priority content</span></div>
<div class="box box-secondary">Content<span class="meta">main body section</span></div>
<div class="box">Footer CTA<span class="meta">conversion action</span></div>
</div>
</section>
<section class="card stack">
<h2>Pattern 2: Content + Sidebar</h2>
<ul class="explain-list">
<li>Starts as one column for mobile readability.</li>
<li>At <code>820px+</code> it becomes a <code>2fr 1fr</code> split layout.</li>
</ul>
<!-- At >= 820px, this changes from stacked to split -->
<div class="pattern split">
<div class="box">Main content column<span class="meta">2fr at desktop</span></div>
<div class="box box-secondary">Sidebar / metadata<span class="meta">1fr at desktop</span></div>
</div>
</section>
<section class="card stack">
<h2>Pattern 3: Card Gallery</h2>
<ul class="explain-list">
<li><code>auto-fit + minmax</code> creates responsive columns automatically.</li>
<li>Cards expand/contract without writing multiple media queries.</li>
</ul>
<!-- auto-fit with minmax creates responsive columns without many media queries -->
<div class="pattern gallery">
<div class="box">Card A<span class="meta">min width: 180px</span></div>
<div class="box">Card B<span class="meta">auto-fit track</span></div>
<div class="box">Card C<span class="meta">auto-fit track</span></div>
<div class="box">Card D<span class="meta">auto-fit track</span></div>
</div>
</section>
</main> /* lesson.css base */
/* Shared design tokens used by all CSS demos.
Project setup pattern: define tokens once in :root, then reuse with var(--token). */
:root {
/* Surface/background colors */
--bg: #f8fafc;
--card: #ffffff;
/* Text colors */
--ink: #111827;
--subtle: #4b5563;
/* Border and accent colors */
--line: #d1d5db;
--accent: #0f766e;
}
/* Make element sizing predictable: width includes border/padding */
*,
*::before,
*::after {
box-sizing: border-box;
}
/* Base page styles reused by each lesson page */
body {
margin: 0;
font-family: "Inter", "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
color: var(--ink);
background: var(--bg);
line-height: 1.5;
}
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
outline: 3px solid var(--accent);
outline-offset: 2px;
}
/* Content container */
main {
max-width: 960px;
margin: 0 auto;
padding: 2rem 1rem 3rem;
}
/* Generic content card */
.card {
background: var(--card);
border: 1px solid var(--line);
border-radius: 10px;
padding: 1rem;
}
/* Vertical rhythm helper: adds top margin to siblings only */
.stack > * + * {
margin-top: 0.75rem;
}
/* Secondary explanatory text */
.hint {
color: var(--subtle);
font-size: 0.95rem;
}
/* Short explanatory callout block for each lesson section */
.callout {
border-left: 3px solid var(--accent);
background: #f0fdfa;
padding: 0.6rem 0.75rem;
border-radius: 6px;
color: #134e4a;
font-size: 0.92rem;
}
/* Bullet list used to explain what each demo element is showing */
.explain-list {
margin: 0;
padding-left: 1.2rem;
}
.explain-list li + li {
margin-top: 0.35rem;
}
/* Inline CSS rule label shown inside demo elements */
.meta {
display: block;
margin-top: 0.3rem;
font-size: 0.72rem;
color: #475569;
}
/* Optional button helper class (not required in every demo) */
.button {
display: inline-block;
border: 0;
border-radius: 8px;
background: var(--accent);
color: #fff;
padding: 0.5rem 0.75rem;
text-decoration: none;
}
/* lesson-specific */
.pattern {
border: 1px solid var(--line);
border-radius: 8px;
padding: 0.75rem;
background: #fff;
}
/* Pattern 1: stacked layout for mobile-first approach */
.stacked {
display: grid;
gap: 0.75rem;
}
/* Pattern 2: split layout at a medium breakpoint */
.split {
display: grid;
gap: 0.75rem;
grid-template-columns: 1fr;
}
/* Pattern 3: simple card gallery using auto-fit */
.gallery {
display: grid;
gap: 0.75rem;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}
.box {
min-height: 90px;
border-radius: 8px;
border: 1px solid #bfdbfe;
background: #dbeafe;
padding: 0.75rem;
}
.box-secondary {
border-color: #bbf7d0;
background: #dcfce7;
}
@media (min-width: 820px) {
.split {
grid-template-columns: 2fr 1fr;
}
}