CSS Intermediate

CSS Flexbox Layout

Imran Nadwi
111 views 40 min read

Understanding Flexbox - A Flexible Layout System

Flexbox is a powerful CSS layout system that makes it easy to create flexible, responsive layouts. Instead of manually calculating sizes and positions, Flexbox automatically arranges items based on rules you define. It's like having a smart layout assistant.

Flexbox is best used for:

  • Navigation bars - Distribute links evenly across the top
  • Card layouts - Create responsive grids of cards
  • Centered content - Center items both horizontally and vertically
  • Space distribution - Automatically space items with gaps
  • Mobile-friendly layouts - Items automatically adjust to screen size

Container vs Items

Flexbox has two main parts:

  • Flex Container: The parent element with display: flex
  • Flex Items: The direct children of the flex container
<div class="flex-container">  <!-- This is the container -->
    <div class="flex-item">Item 1</div>  <!-- These are items -->
    <div class="flex-item">Item 2</div>
    <div class="flex-item">Item 3</div>
</div>

Step 1: Creating a Flex Container

To use Flexbox, add display: flex to the parent element:

.flex-container {
    display: flex;  /* Activates Flexbox */
}

This immediately changes how children are arranged (horizontally by default).

Real-World Example 1: Navigation Bar

<nav class="navbar">
    <div class="logo">MyLogo</div>
    <ul class="nav-links">
        <li><a href="/">Home</a></li>
        <li><a href="/about">About</a></li>
        <li><a href="/contact">Contact</a></li>
    </ul>
</nav>

<style>
.navbar {
    display: flex;              /* Make it a flex container */
    justify-content: space-between; /* Space logo and links apart */
    align-items: center;        /* Vertically center items */
    padding: 15px;
    background-color: #333;
    color: white;
}

.nav-links {
    display: flex;              /* Flex the links too */
    list-style: none;
    gap: 30px;                  /* Space between links */
}

.nav-links a {
    color: white;
    text-decoration: none;
}
</style>

Container Properties - Control Arrangement

flex-direction (Row vs Column)

Controls whether items flow horizontally or vertically:

.container {
    display: flex;
    flex-direction: row;        /* Horizontal (default) */
    /* flex-direction: column; */ /* Vertical */
}

justify-content (Horizontal Distribution)

Controls spacing along the main axis (left-right if flex-direction: row):

justify-content: flex-start;    /* Items on the left */
justify-content: center;         /* Items in the center */
justify-content: flex-end;       /* Items on the right */
justify-content: space-between;  /* Space evenly (edges touch) */
justify-content: space-around;   /* Space evenly (even edges) */
justify-content: space-evenly;   /* Equal space everywhere */

align-items (Vertical Alignment)

Controls alignment on the cross-axis (top-bottom if flex-direction: row):

align-items: flex-start;        /* Items at top */
align-items: center;            /* Items centered vertically */
align-items: flex-end;          /* Items at bottom */
align-items: stretch;           /* Items stretch to fill (default) */

gap (Space Between Items)

Automatically adds space between items (much easier than margins):

.container {
    display: flex;
    gap: 20px;  /* 20px space between each item */
}

Real-World Example 2: Card Grid

<div class="card-container">
    <div class="card">
        <h3>Card 1</h3>
        <p>Content here</p>
    </div>
    <div class="card">
        <h3>Card 2</h3>
        <p>Content here</p>
    </div>
    <div class="card">
        <h3>Card 3</h3>
        <p>Content here</p>
    </div>
</div>

<style>
.card-container {
    display: flex;
    flex-wrap: wrap;            /* Wrap to next line if needed */
    gap: 20px;
}

.card {
    flex: 1 1 250px;            /* Grow, shrink, base 250px */
    background-color: white;
    border: 1px solid #ddd;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
</style>

Item Properties - Control Individual Items

flex Property (Growth and Shrinking)

The flex property is shorthand for flex-grow, flex-shrink, and flex-basis:

/* flex: grow shrink basis */
.item { flex: 1 1 250px; }

/* This means:
   - Grow: Yes (1 = share available space equally)
   - Shrink: Yes (1 = shrink if container is too small)
   - Basis: 250px minimum width
*/

flex-grow (Share Extra Space)

How much extra space an item should take if available:

.sidebar { flex-grow: 0; }  /* Don't grow */
.content { flex-grow: 1; }  /* Take available space */

/* If content has flex-grow: 2, it gets twice the space */

align-self (Override Alignment)

Override align-items for a specific item:

.container {
    display: flex;
    align-items: center;
}

.special-item {
    align-self: flex-start;  /* This item aligns to top */
}

Real-World Example 3: Two-Column Layout

<div class="layout">
    <aside class="sidebar">
        <h3>Sidebar</h3>
        <!-- Sidebar content -->
    </aside>
    <main class="content">
        <h1>Main Content</h1>
        <!-- Main content -->
    </main>
</div>

<style>
.layout {
    display: flex;
    gap: 20px;
}

.sidebar {
    flex: 0 0 300px;      /* Fixed 300px width */
    background-color: #f5f5f5;
    padding: 20px;
}

.content {
    flex: 1 1 0;          /* Takes remaining space */
    padding: 20px;
}

/* Mobile: stack vertically */
@media (max-width: 768px) {
    .layout {
        flex-direction: column;
    }
    
    .sidebar {
        flex: 0 0 auto;
    }
}
</style>

Real-World Example 4: Centered Content

<div class="centered-box">
    <h1>Welcome</h1>
    <p>This content is perfectly centered</p>
    <button>Get Started</button>
</div>

<style>
.centered-box {
    display: flex;
    flex-direction: column;
    justify-content: center;     /* Center vertically */
    align-items: center;         /* Center horizontally */
    gap: 15px;
    height: 100vh;              /* Full viewport height */
    text-align: center;
}
</style>

Real-World Example 5: Button Group

<div class="button-group">
    <button>Cancel</button>
    <button class="primary">Save</button>
</div>

<style>
.button-group {
    display: flex;
    gap: 10px;
    justify-content: flex-end;  /* Buttons on the right */
}

button {
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    background-color: #f0f0f0;
    color: #333;
}

button.primary {
    background-color: #007bff;
    color: white;
}
</style>

flex-wrap (Wrap to Multiple Lines)

By default, flex items stay on one line. Use flex-wrap to make them wrap:

.container {
    display: flex;
    flex-wrap: wrap;       /* Items wrap to next line */
    gap: 15px;
}

.item {
    flex: 1 1 200px;       /* Min 200px, grow to fill */
}

Common Flexbox Patterns

Pattern 1: Space-Between Navigation

.navbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

Pattern 2: Responsive Card Grid

.cards {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
}

.card {
    flex: 1 1 300px;  /* Min 300px width */
}

Pattern 3: Sidebar Layout

.page {
    display: flex;
}

.sidebar {
    flex: 0 0 250px;  /* Fixed width */
}

.main {
    flex: 1;          /* Takes remaining space */
}

Pattern 4: Centered Hero Section

.hero {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 20px;
    text-align: center;
}

When NOT to Use Flexbox

Flexbox is great for one-dimensional layouts (rows or columns). For two-dimensional layouts (rows AND columns), use CSS Grid instead (covered in the next lesson).

Summary

You now understand:

  • How Flexbox makes flexible layouts easy
  • Container properties: flex-direction, justify-content, align-items, gap
  • Item properties: flex, flex-grow, align-self
  • Real-world patterns: navigation, cards, sidebars, centered content
  • How to make layouts responsive with flex-wrap and media queries

Flexbox is one of the most important CSS tools. Master it and you can build almost any layout. Next, we'll explore CSS Grid for more complex two-dimensional layouts.