Lesson 12: Flexbox Properties - Advanced Control

What You'll Learn

  • flex-grow, flex-shrink, flex-basis
  • The flex shorthand property
  • align-self for individual items
  • order property
  • Advanced alignment with align-content
  • Building flexible, responsive components

Why This Matters

These properties give you fine-tuned control over how flex items grow, shrink, and align. They're essential for creating truly flexible, responsive layouts that adapt to different screen sizes.


Part 1: Understanding Flex Items

So far, we've styled the container. Now let's control individual items!


Part 2: Flex-Grow

Controls how items grow to fill available space.

Default (No Growth)

.item {
    flex-grow: 0;  / Default - doesn't grow /
}

Equal Growth

.item {
    flex-grow: 1;  / All items grow equally /
}
Example:
<div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
</div>
.container {
    display: flex;
    gap: 10px;
}

.item {
    flex-grow: 1;  / Each takes 1/3 of space /
    padding: 20px;
    background-color: #3498db;
    color: white;
    text-align: center;
}

All items equally share available space!

Unequal Growth

.item-1 {
    flex-grow: 1;  / Gets 1 part /
}

.item-2 {
    flex-grow: 2;  / Gets 2 parts (twice as much) /
}

.item-3 {
    flex-grow: 1;  / Gets 1 part /
}
HTML:
<div class="container">
    <div class="item item-1">1</div>
    <div class="item item-2">2 (bigger)</div>
    <div class="item item-3">3</div>
</div>

Item 2 grows twice as much as items 1 and 3!


Part 3: Flex-Shrink

Controls how items shrink when there's not enough space.

Default Behavior

.item {
    flex-shrink: 1;  / Default - can shrink /
}

Prevent Shrinking

.item {
    flex-shrink: 0;  / Won't shrink below content size /
}
Example - Sidebar Layout:
<div class="layout">
    <aside class="sidebar">Sidebar</aside>
    <main class="content">Main Content</main>
</div>
.layout {
    display: flex;
    gap: 20px;
}

.sidebar {
    width: 250px;
    flex-shrink: 0;  / Sidebar stays 250px /
    background-color: #f0f0f0;
    padding: 20px;
}

.content {
    flex-grow: 1;  / Content fills remaining space /
    padding: 20px;
}

Sidebar stays fixed width, content is flexible!


Part 4: Flex-Basis

Sets the initial size of a flex item before growing/shrinking.

Using Flex-Basis

.item {
    flex-basis: 200px;  / Start at 200px /
}
Think of it as "ideal width" for row or "ideal height" for column.

Flex-Basis vs Width

/ These are similar but flex-basis is better for flex items /
.item {
    width: 200px;       / Fixed width /
    flex-basis: 200px;  / Flexible starting point /
}
Example:
<div class="container">
    <div class="item">Short</div>
    <div class="item">Medium Length Text</div>
    <div class="item">Very Long Content That Wraps</div>
</div>
.container {
    display: flex;
    gap: 10px;
}

.item {
    flex-basis: 150px;  / Start at 150px /
    flex-grow: 1;       / But can grow /
    padding: 20px;
    background-color: #3498db;
    color: white;
}

Part 5: The Flex Shorthand

Combines flex-grow, flex-shrink, and flex-basis:

.item {
    flex: [grow] [shrink] [basis];
}

Common Patterns

/ Don't grow or shrink - fixed size /
.item {
    flex: 0 0 200px;
    / grow:0, shrink:0, basis:200px /
}

/ Grow but don't shrink /
.item {
    flex: 1 0 auto;
    / grow:1, shrink:0, basis:auto /
}

/ Flexible - most common /
.item {
    flex: 1;
    / shorthand for: 1 1 0% /
    / Grow and shrink equally /
}

/ Auto sizing /
.item {
    flex: auto;
    / shorthand for: 1 1 auto /
    / Based on content size /
}

/ No flexibility /
.item {
    flex: none;
    / shorthand for: 0 0 auto /
    / Fixed to content size /
}

Practical Example - Dashboard Layout

<div class="dashboard">
    <aside class="sidebar">Menu</aside>
    <main class="main">Content</main>
    <aside class="widgets">Widgets</aside>
</div>
.dashboard {
    display: flex;
    gap: 20px;
    height: 100vh;
}

.sidebar {
    flex: 0 0 200px;  / Fixed 200px /
    background-color: #2c3e50;
    color: white;
    padding: 20px;
}

.main {
    flex: 1;  / Takes remaining space /
    background-color: white;
    padding: 20px;
}

.widgets {
    flex: 0 0 300px;  / Fixed 300px /
    background-color: #ecf0f1;
    padding: 20px;
}

Part 6: Align-Self

Override align-items for individual items:

.container {
    display: flex;
    align-items: flex-start;  / All items at top /
    height: 200px;
}

.item-special {
    align-self: flex-end;  / This one at bottom /
}
Values:
  • auto (default - inherit from parent)
  • flex-start
  • flex-end
  • center
  • baseline
  • stretch
Example:
<div class="container">
    <div class="item">1</div>
    <div class="item special">2 (different)</div>
    <div class="item">3</div>
</div>
.container {
    display: flex;
    align-items: flex-start;
    height: 200px;
    gap: 10px;
    background-color: #f0f0f0;
}

.item {
    padding: 20px;
    background-color: #3498db;
    color: white;
}

.special {
    align-self: flex-end;  / Aligns to bottom /
    background-color: #e74c3c;
}

Part 7: Order Property

Change the visual order of items:

.item-1 {
    order: 2;  / Appears second /
}

.item-2 {
    order: 3;  / Appears third /
}

.item-3 {
    order: 1;  / Appears first /
}

Default order is 0. Lower numbers come first.

Example:
<div class="container">
    <div class="item item-1">I'm first in HTML</div>
    <div class="item item-2">I'm second in HTML</div>
    <div class="item item-3">I'm third in HTML</div>
</div>
.item-1 { order: 3; }  / Shows last /
.item-2 { order: 1; }  / Shows first /
.item-3 { order: 2; }  / Shows middle /

Visual order: 2, 3, 1

Use case: Reordering content for mobile layouts!


Part 8: Align-Content (Multi-line Flex Containers)

When using flex-wrap, controls spacing between lines:

.container {
    display: flex;
    flex-wrap: wrap;
    align-content: space-between;  / Space between rows /
}
Values:
  • flex-start - Lines packed to start
  • flex-end - Lines packed to end
  • center - Lines centered
  • space-between - Max space between lines
  • space-around - Equal space around lines
  • space-evenly - Even space everywhere
  • stretch (default) - Lines stretch to fill
Example:
<div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
</div>
.container {
    display: flex;
    flex-wrap: wrap;
    align-content: space-between;
    height: 400px;
    gap: 10px;
}

.item {
    flex: 0 0 150px;
    height: 100px;
    background-color: #3498db;
    color: white;
    display: flex;
    justify-content: center;
    align-items: center;
}

Part 9: Complete Example - Responsive Card Grid

<!DOCTYPE html>
<html>
<head>
    <title>Flexible Card Grid</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="page">
        <header class="header">
            <h1>Product Catalog</h1>
        </header>
        
        <div class="content">
            <aside class="filters">
                <h2>Filters</h2>
                <ul>
                    <li>Category 1</li>
                    <li>Category 2</li>
                    <li>Category 3</li>
                </ul>
            </aside>
            
            <main class="products">
                <div class="product-card">
                    <div class="product-image">📱</div>
                    <h3>Product 1</h3>
                    <p class="price">$99</p>
                    <button>Add to Cart</button>
                </div>
                
                <div class="product-card featured">
                    <div class="badge">Featured</div>
                    <div class="product-image">💻</div>
                    <h3>Product 2</h3>
                    <p class="price">$199</p>
                    <button>Add to Cart</button>
                </div>
                
                <div class="product-card">
                    <div class="product-image">⌚</div>
                    <h3>Product 3</h3>
                    <p class="price">$149</p>
                    <button>Add to Cart</button>
                </div>
                
                <div class="product-card">
                    <div class="product-image">🎧</div>
                    <h3>Product 4</h3>
                    <p class="price">$79</p>
                    <button>Add to Cart</button>
                </div>
                
                <div class="product-card">
                    <div class="product-image">📷</div>
                    <h3>Product 5</h3>
                    <p class="price">$299</p>
                    <button>Add to Cart</button>
                </div>
                
                <div class="product-card">
                    <div class="product-image">🎮</div>
                    <h3>Product 6</h3>
                    <p class="price">$399</p>
                    <button>Add to Cart</button>
                </div>
            </main>
        </div>
    </div>
</body>
</html>
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: Arial, sans-serif;
    background-color: #f5f5f5;
}

.page {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

/ Header /
.header {
    background-color: #2c3e50;
    color: white;
    padding: 30px;
    text-align: center;
}

/ Content Area /
.content {
    display: flex;
    flex: 1;
    gap: 20px;
    padding: 20px;
    max-width: 1400px;
    margin: 0 auto;
    width: 100%;
}

/ Sidebar /
.filters {
    flex: 0 0 200px;  / Fixed width sidebar /
    background-color: white;
    padding: 20px;
    border-radius: 8px;
    height: fit-content;
}

.filters h2 {
    margin-bottom: 15px;
    font-size: 18px;
}

.filters ul {
    list-style: none;
}

.filters li {
    padding: 8px 0;
    cursor: pointer;
}

.filters li:hover {
    color: #3498db;
}

/ Products Grid /
.products {
    flex: 1;  / Takes remaining space /
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    align-content: flex-start;
}

/ Product Cards /
.product-card {
    flex: 0 0 calc(33.333% - 14px);  / 3 columns /
    background-color: white;
    border-radius: 8px;
    padding: 20px;
    text-align: center;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    display: flex;
    flex-direction: column;
    position: relative;
}

.product-card.featured {
    border: 2px solid #3498db;
}

.badge {
    position: absolute;
    top: -10px;
    right: 10px;
    background-color: #e74c3c;
    color: white;
    padding: 5px 10px;
    border-radius: 20px;
    font-size: 12px;
    font-weight: bold;
}

.product-image {
    font-size: 80px;
    margin-bottom: 15px;
}

.product-card h3 {
    margin-bottom: 10px;
    color: #2c3e50;
}

.price {
    font-size: 24px;
    font-weight: bold;
    color: #27ae60;
    margin-bottom: 15px;
}

.product-card button {
    margin-top: auto;  / Push to bottom /
    padding: 10px 20px;
    background-color: #3498db;
    color: white;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    font-size: 14px;
    font-weight: bold;
}

.product-card button:hover {
    background-color: #2980b9;
}

/ Responsive /
@media (max-width: 900px) {
    .product-card {
        flex: 0 0 calc(50% - 10px);  / 2 columns on tablets /
    }
}

@media (max-width: 600px) {
    .content {
        flex-direction: column;
    }
    
    .filters {
        flex: none;
        order: -1;  / Move filters to top on mobile /
    }
    
    .product-card {
        flex: 0 0 100%;  / 1 column on mobile /
    }
}

Practice Exercises

Exercise 1: Holy Grail Layout

Create the classic layout:

  • Fixed header
  • Fixed footer
  • Sidebar (fixed width)
  • Main content (flexible)
  • Another sidebar (fixed width)

Exercise 2: Pricing Cards

Create 3 pricing cards where:

  • All have equal height
  • Features list grows to push button to bottom
  • Middle card is highlighted (larger)
  • Use flex properties for flexibility

Exercise 3: Image Gallery

Create an image gallery:

  • Items wrap to new rows
  • All items same size
  • Gap between items
  • Responsive (4 columns → 2 → 1)

What You Learned

  • ✅ flex-grow for item expansion
  • ✅ flex-shrink for item compression
  • ✅ flex-basis for initial sizing
  • ✅ flex shorthand property
  • ✅ align-self for individual alignment
  • ✅ order property for visual reordering
  • ✅ align-content for multi-line containers
  • ✅ Building complex flexible layouts

What's Next?

In the next lesson, you'll learn about Responsive Design - making your websites work beautifully on all screen sizes!