Flexbox Utilities
Introduction to Flexbox in Tailwind
Flexbox is one of the most powerful layout systems in CSS, and Tailwind provides comprehensive utilities to harness its full potential. Flexbox is perfect for creating responsive layouts, aligning content, and distributing space efficiently.
Basic Flex Container
To create a flex container, use the flex utility:
<!-- Basic flex container -->
<div class="flex">
<div class="bg-blue-500 text-white p-4">Item 1</div>
<div class="bg-green-500 text-white p-4">Item 2</div>
<div class="bg-red-500 text-white p-4">Item 3</div>
</div>
<!-- Inline flex container -->
<div class="inline-flex">
<div class="bg-blue-500 text-white p-2">Item 1</div>
<div class="bg-green-500 text-white p-2">Item 2</div>
</div>
Flex Direction
Control the direction of flex items:
<!-- Row (default) -->
<div class="flex flex-row">
<div class="bg-blue-500 text-white p-4">1</div>
<div class="bg-green-500 text-white p-4">2</div>
<div class="bg-red-500 text-white p-4">3</div>
</div>
<!-- Row reverse -->
<div class="flex flex-row-reverse">
<div class="bg-blue-500 text-white p-4">1</div>
<div class="bg-green-500 text-white p-4">2</div>
<div class="bg-red-500 text-white p-4">3</div>
</div>
<!-- Column -->
<div class="flex flex-col">
<div class="bg-blue-500 text-white p-4">1</div>
<div class="bg-green-500 text-white p-4">2</div>
<div class="bg-red-500 text-white p-4">3</div>
</div>
<!-- Column reverse -->
<div class="flex flex-col-reverse">
<div class="bg-blue-500 text-white p-4">1</div>
<div class="bg-green-500 text-white p-4">2</div>
<div class="bg-red-500 text-white p-4">3</div>
</div>
Flex Wrap
Control whether flex items wrap to new lines:
<!-- No wrap (default) -->
<div class="flex flex-nowrap w-64">
<div class="bg-blue-500 text-white p-4 w-32">Item 1</div>
<div class="bg-green-500 text-white p-4 w-32">Item 2</div>
<div class="bg-red-500 text-white p-4 w-32">Item 3</div>
</div>
<!-- Wrap -->
<div class="flex flex-wrap w-64">
<div class="bg-blue-500 text-white p-4 w-32">Item 1</div>
<div class="bg-green-500 text-white p-4 w-32">Item 2</div>
<div class="bg-red-500 text-white p-4 w-32">Item 3</div>
</div>
<!-- Wrap reverse -->
<div class="flex flex-wrap-reverse w-64">
<div class="bg-blue-500 text-white p-4 w-32">Item 1</div>
<div class="bg-green-500 text-white p-4 w-32">Item 2</div>
<div class="bg-red-500 text-white p-4 w-32">Item 3</div>
</div>
Justify Content (Main Axis Alignment)
Align items along the main axis:
<!-- Start (default) -->
<div class="flex justify-start">
<div class="bg-blue-500 text-white p-4">1</div>
<div class="bg-green-500 text-white p-4">2</div>
<div class="bg-red-500 text-white p-4">3</div>
</div>
<!-- End -->
<div class="flex justify-end">
<div class="bg-blue-500 text-white p-4">1</div>
<div class="bg-green-500 text-white p-4">2</div>
<div class="bg-red-500 text-white p-4">3</div>
</div>
<!-- Center -->
<div class="flex justify-center">
<div class="bg-blue-500 text-white p-4">1</div>
<div class="bg-green-500 text-white p-4">2</div>
<div class="bg-red-500 text-white p-4">3</div>
</div>
<!-- Space between -->
<div class="flex justify-between">
<div class="bg-blue-500 text-white p-4">1</div>
<div class="bg-green-500 text-white p-4">2</div>
<div class="bg-red-500 text-white p-4">3</div>
</div>
<!-- Space around -->
<div class="flex justify-around">
<div class="bg-blue-500 text-white p-4">1</div>
<div class="bg-green-500 text-white p-4">2</div>
<div class="bg-red-500 text-white p-4">3</div>
</div>
<!-- Space evenly -->
<div class="flex justify-evenly">
<div class="bg-blue-500 text-white p-4">1</div>
<div class="bg-green-500 text-white p-4">2</div>
<div class="bg-red-500 text-white p-4">3</div>
</div>
Align Items (Cross Axis Alignment)
Align items along the cross axis:
<!-- Stretch (default) -->
<div class="flex items-stretch h-32">
<div class="bg-blue-500 text-white p-4">1</div>
<div class="bg-green-500 text-white p-4">2</div>
<div class="bg-red-500 text-white p-4">3</div>
</div>
<!-- Start -->
<div class="flex items-start h-32">
<div class="bg-blue-500 text-white p-4">1</div>
<div class="bg-green-500 text-white p-4">2</div>
<div class="bg-red-500 text-white p-4">3</div>
</div>
<!-- End -->
<div class="flex items-end h-32">
<div class="bg-blue-500 text-white p-4">1</div>
<div class="bg-green-500 text-white p-4">2</div>
<div class="bg-red-500 text-white p-4">3</div>
</div>
<!-- Center -->
<div class="flex items-center h-32">
<div class="bg-blue-500 text-white p-4">1</div>
<div class="bg-green-500 text-white p-4">2</div>
<div class="bg-red-500 text-white p-4">3</div>
</div>
<!-- Baseline -->
<div class="flex items-baseline h-32">
<div class="bg-blue-500 text-white p-4 text-xs">Small</div>
<div class="bg-green-500 text-white p-4 text-lg">Large</div>
<div class="bg-red-500 text-white p-4">Normal</div>
</div>
Align Content (Multi-line Alignment)
Align wrapped lines:
<!-- Start -->
<div class="flex flex-wrap content-start h-64 w-64">
<div class="bg-blue-500 text-white p-4 w-32">1</div>
<div class="bg-green-500 text-white p-4 w-32">2</div>
<div class="bg-red-500 text-white p-4 w-32">3</div>
<div class="bg-yellow-500 text-white p-4 w-32">4</div>
</div>
<!-- Center -->
<div class="flex flex-wrap content-center h-64 w-64">
<div class="bg-blue-500 text-white p-4 w-32">1</div>
<div class="bg-green-500 text-white p-4 w-32">2</div>
<div class="bg-red-500 text-white p-4 w-32">3</div>
<div class="bg-yellow-500 text-white p-4 w-32">4</div>
</div>
<!-- Space between -->
<div class="flex flex-wrap content-between h-64 w-64">
<div class="bg-blue-500 text-white p-4 w-32">1</div>
<div class="bg-green-500 text-white p-4 w-32">2</div>
<div class="bg-red-500 text-white p-4 w-32">3</div>
<div class="bg-yellow-500 text-white p-4 w-32">4</div>
</div>
Flex Item Properties
Flex Grow
Control how flex items grow:
<div class="flex">
<div class="flex-none bg-blue-500 text-white p-4 w-32">Fixed width</div>
<div class="flex-1 bg-green-500 text-white p-4">Grows to fill space</div>
<div class="flex-none bg-red-500 text-white p-4 w-32">Fixed width</div>
</div>
<!-- Different grow values -->
<div class="flex">
<div class="flex-1 bg-blue-500 text-white p-4">Grow 1</div>
<div class="flex-2 bg-green-500 text-white p-4">Grow 2</div>
<div class="flex-1 bg-red-500 text-white p-4">Grow 1</div>
</div>
Flex Shrink
Control how flex items shrink:
<div class="flex w-96">
<div class="flex-shrink-0 bg-blue-500 text-white p-4 w-64">Won't shrink</div>
<div class="flex-shrink bg-green-500 text-white p-4 w-64">Will shrink</div>
</div>
Align Self
Override align-items for individual items:
<div class="flex items-start h-32">
<div class="bg-blue-500 text-white p-4">Start</div>
<div class="self-center bg-green-500 text-white p-4">Center</div>
<div class="self-end bg-red-500 text-white p-4">End</div>
<div class="self-stretch bg-yellow-500 text-white p-4">Stretch</div>
</div>
Order
Change the visual order of flex items:
<div class="flex">
<div class="order-3 bg-blue-500 text-white p-4">
First in HTML, third visually
</div>
<div class="order-1 bg-green-500 text-white p-4">
Second in HTML, first visually
</div>
<div class="order-2 bg-red-500 text-white p-4">
Third in HTML, second visually
</div>
</div>
Gap
Add space between flex items:
<!-- Gap between all items -->
<div class="flex gap-4">
<div class="bg-blue-500 text-white p-4">Item 1</div>
<div class="bg-green-500 text-white p-4">Item 2</div>
<div class="bg-red-500 text-white p-4">Item 3</div>
</div>
<!-- Different horizontal and vertical gaps -->
<div class="flex flex-wrap gap-x-8 gap-y-4">
<div class="bg-blue-500 text-white p-4">Item 1</div>
<div class="bg-green-500 text-white p-4">Item 2</div>
<div class="bg-red-500 text-white p-4">Item 3</div>
<div class="bg-yellow-500 text-white p-4">Item 4</div>
</div>
Common Flexbox Patterns
Centering Content
<!-- Perfect centering -->
<div class="flex items-center justify-center h-64 bg-gray-100">
<div class="bg-blue-500 text-white p-8 rounded-lg">
Perfectly centered content
</div>
</div>
Navigation Bar
<nav class="flex items-center justify-between p-4 bg-white shadow">
<div class="flex items-center space-x-4">
<img src="logo.png" alt="Logo" class="h-8 w-8" />
<span class="font-bold text-xl">Brand</span>
</div>
<div class="flex items-center space-x-6">
<a href="#" class="text-gray-600 hover:text-gray-900">Home</a>
<a href="#" class="text-gray-600 hover:text-gray-900">About</a>
<a href="#" class="text-gray-600 hover:text-gray-900">Contact</a>
</div>
<div class="flex items-center space-x-2">
<button class="bg-blue-500 text-white px-4 py-2 rounded">Login</button>
<button class="bg-gray-200 text-gray-800 px-4 py-2 rounded">Sign Up</button>
</div>
</nav>
Card Layout
<div class="flex flex-col bg-white rounded-lg shadow-md overflow-hidden">
<img src="image.jpg" alt="Card image" class="h-48 w-full object-cover" />
<div class="flex-1 p-6">
<h3 class="text-xl font-bold mb-2">Card Title</h3>
<p class="text-gray-600 mb-4">
Card description that can be multiple lines long.
</p>
</div>
<div class="flex items-center justify-between p-6 bg-gray-50">
<span class="text-sm text-gray-500">2 hours ago</span>
<button class="bg-blue-500 text-white px-4 py-2 rounded text-sm">
Read More
</button>
</div>
</div>
Sidebar Layout
<div class="flex h-screen">
<!-- Sidebar -->
<div class="flex flex-col w-64 bg-gray-800 text-white">
<div class="p-4 border-b border-gray-700">
<h2 class="text-xl font-bold">Dashboard</h2>
</div>
<nav class="flex-1 p-4">
<ul class="space-y-2">
<li>
<a href="#" class="block p-2 rounded hover:bg-gray-700">Home</a>
</li>
<li>
<a href="#" class="block p-2 rounded hover:bg-gray-700">Users</a>
</li>
<li>
<a href="#" class="block p-2 rounded hover:bg-gray-700">Settings</a>
</li>
</ul>
</nav>
<div class="p-4 border-t border-gray-700">
<button class="w-full bg-red-600 text-white p-2 rounded">Logout</button>
</div>
</div>
<!-- Main content -->
<div class="flex-1 flex flex-col">
<header class="bg-white shadow p-4">
<h1 class="text-2xl font-bold">Page Title</h1>
</header>
<main class="flex-1 p-6 bg-gray-100">
<p>Main content area</p>
</main>
</div>
</div>
Visual Layout Diagram
Flexbox Container Properties:
┌─────────────────────────────────────────────────────┐
│ Flex Container │
│ │
│ Main Axis (justify-content) │
│ ←─────────────────────────────────────────────→ │
│ ┌─────┐ ┌─────┐ ┌─────┐ ↑ │
│ │ 1 │ │ 2 │ │ 3 │ │ │
│ └─────┘ └─────┘ └─────┘ │ │
│ Cross Axis │
│ (align-items) │
│ ↓ │
└─────────────────────────────────────────────────────┘
Flex Direction Examples:
flex-row: [1] [2] [3]
flex-col: [1]
[2]
[3]
Justify Content Examples:
justify-start: [1][2][3]
justify-center: [1][2][3]
justify-end: [1][2][3]
justify-between: [1] [2] [3]
justify-around: [1] [2] [3]
justify-evenly: [1] [2] [3]
Common Pitfalls & Anti-Patterns
❌ Forgetting Flex Container
<!-- Bad: Using flex utilities without flex container -->
<div>
<div class="justify-center">Won't work</div>
<div class="items-center">Won't work</div>
</div>
✅ Proper Flex Container
<!-- Good: Flex utilities on flex container -->
<div class="flex justify-center items-center">
<div>This works</div>
<div>This works too</div>
</div>
❌ Overcomplicating Simple Layouts
<!-- Bad: Unnecessary complexity -->
<div class="flex flex-col">
<div class="flex justify-center">
<div class="flex items-center">
<span>Simple text</span>
</div>
</div>
</div>
✅ Simple and Clean
<!-- Good: Simple and direct -->
<div class="text-center">
<span>Simple text</span>
</div>
❌ Not Using Semantic HTML
<!-- Bad: Divs for everything -->
<div class="flex">
<div>Logo</div>
<div class="flex">
<div>Home</div>
<div>About</div>
</div>
</div>
✅ Semantic HTML with Flexbox
<!-- Good: Semantic HTML -->
<nav class="flex items-center justify-between">
<div class="logo">Logo</div>
<ul class="flex space-x-4">
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
</ul>
</nav>
When and Why to Use Flexbox
When to Use Flexbox
- One-dimensional layouts (either row or column)
- Component-level layouts (cards, navigation bars, buttons)
- Centering content (both horizontally and vertically)
- Distributing space between elements
- Aligning items with different heights
- Responsive layouts that adapt to content
Why Use Flexbox
- Flexible and responsive by nature
- Easy alignment in both directions
- Content-driven sizing (grows/shrinks based on content)
- Source order independence (visual order can differ from HTML order)
- Excellent browser support
- Intuitive once you understand the main/cross axis concept
Flexbox vs Grid
- Use Flexbox for: One-dimensional layouts, component layouts, alignment
- Use Grid for: Two-dimensional layouts, page layouts, complex positioning
Mini Challenges
Challenge 1: Navigation Component
Create a responsive navigation bar with:
- Logo on the left
- Navigation links in the center
- User actions on the right
- Mobile-friendly layout
Challenge 2: Card Grid
Create a responsive card grid that:
- Shows 1 card per row on mobile
- Shows 2 cards per row on tablet
- Shows 3 cards per row on desktop
- Cards have equal height
Challenge 3: Holy Grail Layout
Create a "holy grail" layout with:
- Header at the top
- Footer at the bottom
- Sidebar on the left
- Main content in the center
- Sidebar and main content fill remaining height
Interview Tips
Q: "When would you choose Flexbox over CSS Grid?"
A: "I choose Flexbox for:
- One-dimensional layouts - when arranging items in a single row or column
- Component-level layouts - navigation bars, card internals, button groups
- Content-driven sizing - when items should grow/shrink based on their content
- Alignment tasks - centering content, aligning items with different heights
- When I need source order independence - changing visual order without changing HTML
I choose Grid for two-dimensional layouts, page-level layouts, and when I need precise control over both rows and columns."
Q: "How do you handle responsive design with Flexbox?"
A: "I handle responsive Flexbox layouts by:
- Using responsive flex direction -
flex-col md:flex-rowto stack on mobile, row on desktop - Responsive justify/align - different alignment at different breakpoints
- Responsive flex properties -
flex-none md:flex-1for different growing behavior - Combining with responsive utilities - width, padding, margin changes
- Using flex-wrap strategically for natural wrapping behavior
- Mobile-first approach - starting with mobile layout and enhancing for larger screens"
Challenge Answers
Answer 1: Navigation Component
<!-- Desktop Navigation -->
<nav class="flex items-center justify-between p-4 bg-white shadow-md">
<!-- Logo -->
<div class="flex items-center space-x-2">
<div class="w-8 h-8 bg-blue-500 rounded"></div>
<span class="text-xl font-bold">Brand</span>
</div>
<!-- Navigation Links (hidden on mobile) -->
<div class="hidden md:flex items-center space-x-8">
<a href="#" class="text-gray-600 hover:text-gray-900 transition-colors"
>Home</a
>
<a href="#" class="text-gray-600 hover:text-gray-900 transition-colors"
>Products</a
>
<a href="#" class="text-gray-600 hover:text-gray-900 transition-colors"
>About</a
>
<a href="#" class="text-gray-600 hover:text-gray-900 transition-colors"
>Contact</a
>
</div>
<!-- User Actions -->
<div class="flex items-center space-x-2">
<button
class="hidden md:block px-4 py-2 text-gray-600 hover:text-gray-900 transition-colors"
>
Login
</button>
<button
class="px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600 transition-colors"
>
Sign Up
</button>
<!-- Mobile menu button -->
<button class="md:hidden p-2">
<svg
class="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 6h16M4 12h16M4 18h16"
></path>
</svg>
</button>
</div>
</nav>
<!-- Mobile Navigation Menu (toggle with JavaScript) -->
<div class="md:hidden bg-white border-t border-gray-200">
<div class="flex flex-col space-y-1 p-4">
<a
href="#"
class="block px-3 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-50 rounded-md"
>Home</a
>
<a
href="#"
class="block px-3 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-50 rounded-md"
>Products</a
>
<a
href="#"
class="block px-3 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-50 rounded-md"
>About</a
>
<a
href="#"
class="block px-3 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-50 rounded-md"
>Contact</a
>
<a
href="#"
class="block px-3 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-50 rounded-md"
>Login</a
>
</div>
</div>
Answer 2: Card Grid
<div class="container mx-auto p-6">
<h2 class="text-3xl font-bold mb-8 text-center">Our Products</h2>
<!-- Responsive Card Grid -->
<div class="flex flex-col md:flex-row md:flex-wrap gap-6">
<!-- Card 1 -->
<div
class="flex flex-col bg-white rounded-lg shadow-md overflow-hidden md:w-[calc(50%-0.75rem)] lg:w-[calc(33.333%-1rem)]"
>
<img
src="https://via.placeholder.com/400x200"
alt="Product 1"
class="h-48 w-full object-cover"
/>
<div class="flex flex-col flex-1 p-6">
<h3 class="text-xl font-bold mb-2">Product Name</h3>
<p class="text-gray-600 mb-4 flex-1">
This is a description of the product that can be multiple lines long
and will help maintain equal card heights.
</p>
<div class="flex items-center justify-between">
<span class="text-2xl font-bold text-blue-600">$99</span>
<button
class="bg-blue-500 text-white px-4 py-2 rounded-md hover:bg-blue-600 transition-colors"
>
Add to Cart
</button>
</div>
</div>
</div>
<!-- Card 2 -->
<div
class="flex flex-col bg-white rounded-lg shadow-md overflow-hidden md:w-[calc(50%-0.75rem)] lg:w-[calc(33.333%-1rem)]"
>
<img
src="https://via.placeholder.com/400x200"
alt="Product 2"
class="h-48 w-full object-cover"
/>
<div class="flex flex-col flex-1 p-6">
<h3 class="text-xl font-bold mb-2">Another Product</h3>
<p class="text-gray-600 mb-4 flex-1">Shorter description.</p>
<div class="flex items-center justify-between">
<span class="text-2xl font-bold text-blue-600">$149</span>
<button
class="bg-blue-500 text-white px-4 py-2 rounded-md hover:bg-blue-600 transition-colors"
>
Add to Cart
</button>
</div>
</div>
</div>
<!-- Card 3 -->
<div
class="flex flex-col bg-white rounded-lg shadow-md overflow-hidden md:w-[calc(50%-0.75rem)] lg:w-[calc(33.333%-1rem)]"
>
<img
src="https://via.placeholder.com/400x200"
alt="Product 3"
class="h-48 w-full object-cover"
/>
<div class="flex flex-col flex-1 p-6">
<h3 class="text-xl font-bold mb-2">Third Product</h3>
<p class="text-gray-600 mb-4 flex-1">
This product has a much longer description that spans multiple lines
to demonstrate how flexbox maintains equal heights across all cards in
the grid.
</p>
<div class="flex items-center justify-between">
<span class="text-2xl font-bold text-blue-600">$79</span>
<button
class="bg-blue-500 text-white px-4 py-2 rounded-md hover:bg-blue-600 transition-colors"
>
Add to Cart
</button>
</div>
</div>
</div>
</div>
</div>
Answer 3: Holy Grail Layout
<div class="flex flex-col h-screen">
<!-- Header -->
<header class="bg-blue-600 text-white p-4">
<div class="container mx-auto">
<h1 class="text-2xl font-bold">Holy Grail Layout</h1>
</div>
</header>
<!-- Main Content Area -->
<div class="flex flex-1 overflow-hidden">
<!-- Sidebar -->
<aside class="w-64 bg-gray-200 p-4 overflow-y-auto">
<nav>
<h2 class="text-lg font-semibold mb-4">Navigation</h2>
<ul class="space-y-2">
<li>
<a
href="#"
class="block p-2 rounded hover:bg-gray-300 transition-colors"
>Dashboard</a
>
</li>
<li>
<a
href="#"
class="block p-2 rounded hover:bg-gray-300 transition-colors"
>Users</a
>
</li>
<li>
<a
href="#"
class="block p-2 rounded hover:bg-gray-300 transition-colors"
>Products</a
>
</li>
<li>
<a
href="#"
class="block p-2 rounded hover:bg-gray-300 transition-colors"
>Orders</a
>
</li>
<li>
<a
href="#"
class="block p-2 rounded hover:bg-gray-300 transition-colors"
>Settings</a
>
</li>
</ul>
</nav>
</aside>
<!-- Main Content -->
<main class="flex-1 p-6 overflow-y-auto bg-gray-50">
<div class="max-w-4xl mx-auto">
<h2 class="text-3xl font-bold mb-6">Main Content</h2>
<div class="bg-white rounded-lg shadow p-6 mb-6">
<h3 class="text-xl font-semibold mb-4">Content Section 1</h3>
<p class="text-gray-600 mb-4">
This is the main content area that takes up the remaining space. It
will grow to fill the available height between the header and
footer.
</p>
<p class="text-gray-600">
The sidebar has a fixed width, and this main content area is
flexible. Both the sidebar and main content will scroll
independently if their content overflows.
</p>
</div>
<div class="bg-white rounded-lg shadow p-6">
<h3 class="text-xl font-semibold mb-4">Content Section 2</h3>
<p class="text-gray-600">
Additional content to demonstrate scrolling behavior when content
exceeds the available height.
</p>
</div>
</div>
</main>
</div>
<!-- Footer -->
<footer class="bg-gray-800 text-white p-4">
<div class="container mx-auto text-center">
<p>© 2024 Your Company. All rights reserved.</p>
</div>
</footer>
</div>