This lesson goes beyond display: flex into the container and item properties that control real layout decisions. Three specimens cover axis direction and alignment, proportional growth with flex shorthand, and wrapping behavior when items exceed the container width.
What this covers
- Main axis vs cross axis:
flex-direction, justify-content, align-items
flex: 1 and flex: 2 growth ratios for proportional sizing
flex-wrap: wrap to let items reflow onto new lines
<main class="stack">
<h1>Flexbox Deep Dive</h1>
<p class="hint">Use this file to practice axes, alignment, growth, shrink, basis, and wrapping behavior.</p>
<p class="callout">Your goal: use container rules and item rules together to control the final layout.</p>
<section class="card stack">
<h2>Main Axis + Cross Axis</h2>
<ul class="explain-list">
<li><strong>Main axis:</strong> set by <code>flex-direction</code> (row vs column).</li>
<li><strong><code>justify-content</code>:</strong> alignment on main axis.</li>
<li><strong><code>align-items</code>:</strong> alignment on cross axis.</li>
</ul>
<!-- flex-direction chooses the main axis direction -->
<div class="flex-demo axis-row">
<div class="item">A<span class="meta">row item</span></div>
<div class="item">B<span class="meta">space-between</span></div>
<div class="item">C<span class="meta">align-items: center</span></div>
</div>
<div class="flex-demo axis-column">
<div class="item">Column A<span class="meta">direction: column</span></div>
<div class="item">Column B<span class="meta">cross-axis start</span></div>
<div class="item">Column C<span class="meta">stacked vertically</span></div>
</div>
</section>
<section class="card stack">
<h2>Flex Growth Ratios</h2>
<ul class="explain-list">
<li><strong><code>flex: 1</code></strong> receives one share of free space.</li>
<li><strong><code>flex: 2</code></strong> receives two shares of free space.</li>
</ul>
<!-- flex: 2 takes twice the free space of flex: 1 -->
<div class="flex-demo">
<div class="item grow-1">flex: 1<span class="meta">1 share</span></div>
<div class="item grow-2">flex: 2<span class="meta">2 shares</span></div>
<div class="item grow-1">flex: 1<span class="meta">1 share</span></div>
</div>
</section>
<section class="card stack">
<h2>Wrapping</h2>
<ul class="explain-list">
<li><strong><code>flex-wrap: wrap</code></strong> allows items to break onto new lines.</li>
<li>Without wrapping, cards may overflow or shrink too much.</li>
</ul>
<!-- Without wrapping, items would overflow or shrink aggressively -->
<div class="flex-demo wrap-demo">
<div class="item wide">Card 1<span class="meta">fixed width: 180px</span></div>
<div class="item wide">Card 2<span class="meta">wrap candidate</span></div>
<div class="item wide">Card 3<span class="meta">wrap candidate</span></div>
<div class="item wide">Card 4<span class="meta">wrap candidate</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 */
.flex-demo {
display: flex;
gap: 0.75rem;
border: 1px solid var(--line);
border-radius: 8px;
background: #fff;
padding: 0.75rem;
min-height: 120px;
}
.item {
border-radius: 8px;
padding: 0.5rem;
background: #dbeafe;
border: 1px solid #93c5fd;
text-align: center;
}
.grow-1 {
flex: 1;
}
.grow-2 {
flex: 2;
background: #fde68a;
border-color: #fcd34d;
}
.axis-row {
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.axis-column {
flex-direction: column;
align-items: flex-start;
}
.wrap-demo {
flex-wrap: wrap;
}
.wide {
width: 180px;
}