Flexbox - Flexible Layout in CSS
Flexbox (Flexible Box Layout) is a CSS layout model designed to arrange elements in one dimension — either horizontally or vertically. With Flexbox, you can easily control the distribution, alignment, and order of elements without resorting to floats or fiddly positioning.
Flexbox works with the concept of a container and items. You apply display: flex to a parent element (the container), and all of its direct children instantly become flex items that you can control flexibly.
Advantages of Flexbox:
- Solves the centering problem that was difficult with older methods
- Controls the distribution of space between elements
- Changes the visual order of elements without changing the HTML
- Makes responsive layouts easier to build
- Controls the height of elements within a single row
Key Flexbox Properties
Flex Container
| Property | Purpose |
|---|---|
display: flex |
Enables Flexbox on the container |
flex-direction |
Sets the direction of the main axis (horizontal/vertical) |
flex-wrap |
Controls whether items wrap to a new row |
justify-content |
Alignment along the main axis (horizontal) |
align-items |
Alignment along the cross axis (vertical) |
align-content |
Alignment between rows when there are multiple rows |
gap |
Spacing between items |
Flex Item
| Property | Purpose |
|---|---|
flex-grow |
How much the item grows to fill the remaining space |
flex-shrink |
How much the item shrinks when space is limited |
flex-basis |
The item's starting size before growing/shrinking |
flex |
Shorthand for grow, shrink, and basis |
order |
Changes the visual order of the item |
align-self |
Overrides align-items for a single item |
Code Example
Basic Flexbox
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flexbox Dasar</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, sans-serif;
padding: 20px;
background: #f0f2f5;
}
h2 {
margin-bottom: 15px;
color: #1a1a2e;
}
/* ===== FLEX DIRECTION ===== */
.direction-section {
margin-bottom: 30px;
}
.flex-container {
display: flex;
gap: 10px;
padding: 20px;
background: #ffffff;
border-radius: 12px;
border: 2px dashed #cbd5e1;
min-height: 100px;
}
.flex-row {
flex-direction: row;
}
.flex-column {
flex-direction: column;
}
.flex-row-reverse {
flex-direction: row-reverse;
}
.flex-column-reverse {
flex-direction: column-reverse;
}
.flex-item {
padding: 15px 25px;
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
border-radius: 8px;
font-weight: 600;
text-align: center;
min-width: 80px;
}
.flex-item:nth-child(2) {
background: linear-gradient(135deg, #f093fb, #f5576c);
}
.flex-item:nth-child(3) {
background: linear-gradient(135deg, #4facfe, #00f2fe);
}
/* ===== JUSTIFY CONTENT ===== */
.justify-section {
margin-bottom: 30px;
}
.justify-start { justify-content: flex-start; }
.justify-center { justify-content: center; }
.justify-end { justify-content: flex-end; }
.justify-between { justify-content: space-between; }
.justify-around { justify-content: space-around; }
.justify-evenly { justify-content: space-evenly; }
/* ===== ALIGN ITEMS ===== */
.align-section {
margin-bottom: 30px;
}
.align-stretch {
align-items: stretch;
}
.align-center {
align-items: center;
}
.align-start {
align-items: flex-start;
}
.align-end {
align-items: flex-end;
}
.align-baseline {
align-items: baseline;
}
.align-container .flex-item:nth-child(1) {
font-size: 12px;
}
.align-container .flex-item:nth-child(2) {
font-size: 20px;
}
.align-container .flex-item:nth-child(3) {
font-size: 16px;
}
/* ===== FLEX WRAP ===== */
.wrap-section {
margin-bottom: 30px;
}
.no-wrap {
flex-wrap: nowrap;
}
.do-wrap {
flex-wrap: wrap;
}
.wrap-container .flex-item {
min-width: 150px;
}
/* ===== FLEX ITEM PROPERTIES ===== */
.item-section {
margin-bottom: 30px;
}
.grow-container .flex-item:nth-child(1) {
flex-grow: 1;
}
.grow-container .flex-item:nth-child(2) {
flex-grow: 2;
}
.grow-container .flex-item:nth-child(3) {
flex-grow: 1;
}
.basis-container .flex-item:nth-child(1) {
flex-basis: 100px;
}
.basis-container .flex-item:nth-child(2) {
flex-basis: 200px;
}
.basis-container .flex-item:nth-child(3) {
flex-basis: 150px;
}
.shrink-container {
width: 400px;
}
.shrink-container .flex-item:nth-child(1) {
flex-shrink: 0;
width: 200px;
}
.shrink-container .flex-item:nth-child(2) {
flex-shrink: 1;
}
.shrink-container .flex-item:nth-child(3) {
flex-shrink: 2;
}
/* ===== ORDER ===== */
.order-container .flex-item:nth-child(1) {
order: 3;
}
.order-container .flex-item:nth-child(2) {
order: 1;
}
.order-container .flex-item:nth-child(3) {
order: 2;
}
/* ===== ALIGN SELF ===== */
.self-container {
height: 200px;
}
.self-container .flex-item:nth-child(1) {
align-self: flex-start;
}
.self-container .flex-item:nth-child(2) {
align-self: center;
}
.self-container .flex-item:nth-child(3) {
align-self: flex-end;
}
.label {
font-size: 12px;
color: #64748b;
margin-bottom: 8px;
font-family: monospace;
background: #e2e8f0;
display: inline-block;
padding: 3px 8px;
border-radius: 4px;
}
</style>
</head>
<body>
<!-- Flex Direction -->
<div class="direction-section">
<h2>Flex Direction</h2>
<span class="label">flex-direction: row</span>
<div class="flex-container flex-row">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
<br>
<span class="label">flex-direction: column</span>
<div class="flex-container flex-column">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
<br>
<span class="label">flex-direction: row-reverse</span>
<div class="flex-container flex-row-reverse">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
<br>
<span class="label">flex-direction: column-reverse</span>
<div class="flex-container flex-column-reverse">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
</div>
<!-- Justify Content -->
<div class="justify-section">
<h2>Justify Content</h2>
<span class="label">justify-content: flex-start</span>
<div class="flex-container justify-start">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
<br>
<span class="label">justify-content: center</span>
<div class="flex-container justify-center">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
<br>
<span class="label">justify-content: space-between</span>
<div class="flex-container justify-between">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
<br>
<span class="label">justify-content: space-around</span>
<div class="flex-container justify-around">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
<br>
<span class="label">justify-content: space-evenly</span>
<div class="flex-container justify-evenly">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
</div>
<!-- Align Items -->
<div class="align-section">
<h2>Align Items</h2>
<span class="label">align-items: stretch</span>
<div class="flex-container align-stretch align-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
<br>
<span class="label">align-items: center</span>
<div class="flex-container align-center align-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
<br>
<span class="label">align-items: baseline</span>
<div class="flex-container align-baseline align-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
</div>
<!-- Flex Wrap -->
<div class="wrap-section">
<h2>Flex Wrap</h2>
<span class="label">flex-wrap: nowrap (default)</span>
<div class="flex-container no-wrap wrap-container">
<div class="flex-item">Item 1</div>
<div class="flex-item">Item 2</div>
<div class="flex-item">Item 3</div>
<div class="flex-item">Item 4</div>
<div class="flex-item">Item 5</div>
</div>
<br>
<span class="label">flex-wrap: wrap</span>
<div class="flex-container do-wrap wrap-container">
<div class="flex-item">Item 1</div>
<div class="flex-item">Item 2</div>
<div class="flex-item">Item 3</div>
<div class="flex-item">Item 4</div>
<div class="flex-item">Item 5</div>
</div>
</div>
<!-- Flex Grow -->
<div class="item-section">
<h2>Flex Grow</h2>
<span class="label">flex-grow: 1 | 2 | 1</span>
<div class="flex-container grow-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
</div>
<!-- Flex Basis -->
<div class="item-section">
<h2>Flex Basis</h2>
<span class="label">flex-basis: 100px | 200px | 150px</span>
<div class="flex-container basis-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
</div>
<!-- Order -->
<div class="item-section">
<h2>Order</h2>
<span class="label">order: 3 | 1 | 2</span>
<div class="flex-container order-container">
<div class="flex-item">1 (order:3)</div>
<div class="flex-item">2 (order:1)</div>
<div class="flex-item">3 (order:2)</div>
</div>
</div>
<!-- Align Self -->
<div class="item-section">
<h2>Align Self</h2>
<span class="label">align-self: flex-start | center | flex-end</span>
<div class="flex-container self-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
</div>
</body>
</html>
Code Explanation
Flex Direction
flex-direction determines the direction of the main axis of the flex container:
row— Items are laid out from left to right (default)column— Items are laid out from top to bottomrow-reverse— Items are laid out from right to leftcolumn-reverse— Items are laid out from bottom to top
.flex-row { flex-direction: row; }
.flex-column { flex-direction: column; }
.flex-row-reverse { flex-direction: row-reverse; }
.flex-column-reverse { flex-direction: column-reverse; }
Justify Content
justify-content controls how items are distributed along the main axis (horizontal for row):
flex-start— Items stick to the start (left)center— Items are centeredflex-end— Items stick to the end (right)space-between— Free space is distributed between items (no spacing at the edges)space-around— Free space around each item (half at the edges)space-evenly— Free space is evenly distributed on all sides, including the edges
Align Items
align-items controls the alignment of items along the cross axis (vertical for row):
stretch— Items stretch to fill the container's height (default)center— Items are vertically centeredflex-start— Items stick to the topflex-end— Items stick to the bottombaseline— Items are aligned based on the text baseline
Flex Wrap
flex-wrap controls whether items move to a new row:
nowrap— All items stay on a single row (default), which may overflowwrap— Items automatically move to a new row when there is not enough space
.flex-container {
flex-wrap: wrap;
gap: 10px;
}
Flex Grow, Shrink, Basis
Properties on a flex item that control sizing:
flex-grow— How much the item grows to fill the remaining space. A value of 2 grows twice as much as a value of 1flex-shrink— How much the item shrinks when space is limitedflex-basis— The item's starting size before grow/shrink is applied
.item-1 { flex-grow: 1; }
.item-2 { flex-grow: 2; } /* Twice as large as item-1 */
.item-3 { flex-basis: 200px; flex-shrink: 0; }
Shorthand flex:
.item {
flex: 1; /* flex-grow: 1, flex-shrink: 1, flex-basis: 0% */
flex: 0 0 200px; /* flex-grow: 0, flex-shrink: 0, flex-basis: 200px */
}
Order
order changes the visual order of items without changing the HTML. By default, all items have a value of 0. The smaller the number, the earlier the item appears:
.item-1 { order: 3; } /* Appears last */
.item-2 { order: 1; } /* Appears first */
.item-3 { order: 2; } /* Appears in the middle */
Align Self
align-self lets a single flex item override the container's align-items:
.flex-item-important {
align-self: center; /* Centered on its own, the others stretch */
}
Everyday Use Cases
1. Simple Navbar
<!DOCTYPE html>
<html lang="en">
<head>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 30px;
background: #1a1a2e;
color: white;
}
.navbar-brand {
font-size: 24px;
font-weight: bold;
}
.navbar-links {
display: flex;
gap: 25px;
list-style: none;
}
.navbar-links a {
color: #e2e8f0;
text-decoration: none;
transition: color 0.3s;
}
.navbar-links a:hover {
color: #818cf8;
}
.navbar-actions {
display: flex;
gap: 10px;
}
.btn {
padding: 8px 20px;
border-radius: 6px;
border: none;
cursor: pointer;
font-weight: 600;
}
.btn-outline {
background: transparent;
border: 2px solid #818cf8;
color: #818cf8;
}
.btn-primary {
background: #818cf8;
color: white;
}
</style>
</head>
<body>
<nav class="navbar">
<div class="navbar-brand">MyBrand</div>
<ul class="navbar-links">
<li><a href="#">Home</a></li>
<li><a href="#">Products</a></li>
<li><a href="#">Tentang</a></li>
<li><a href="#">Kontak</a></li>
</ul>
<div class="navbar-actions">
<button class="btn btn-outline">Log In</button>
<button class="btn btn-primary">Sign Up</button>
</div>
</nav>
</body>
</html>
Explanation: The navbar uses display: flex on the container. justify-content: space-between separates the brand, links, and actions into three sections. align-items: center aligns all elements to the vertical center.
2. Card Layout
<!DOCTYPE html>
<html lang="en">
<head>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 20px;
padding: 20px;
}
.card {
flex: 1 1 280px;
background: white;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.card-image {
width: 100%;
height: 180px;
background: linear-gradient(135deg, #667eea, #764ba2);
}
.card-body {
padding: 20px;
display: flex;
flex-direction: column;
gap: 10px;
}
.card-body h3 {
font-size: 18px;
}
.card-body p {
color: #64748b;
line-height: 1.5;
}
.card-footer {
padding: 0 20px 20px;
display: flex;
justify-content: space-between;
align-items: center;
}
.card-price {
font-size: 20px;
font-weight: bold;
color: #667eea;
}
.btn-buy {
padding: 8px 16px;
background: #667eea;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="card-grid">
<div class="card">
<div class="card-image"></div>
<div class="card-body">
<h3>Product A</h3>
<p>This product's short description is great.</p>
</div>
<div class="card-footer">
<span class="card-price">$25.00</span>
<button class="btn-buy">Beli</button>
</div>
</div>
<div class="card">
<div class="card-image"></div>
<div class="card-body">
<h3>Product B</h3>
<p>This product's short description is really great.</p>
</div>
<div class="card-footer">
<span class="card-price">$15.00</span>
<button class="btn-buy">Beli</button>
</div>
</div>
<div class="card">
<div class="card-image"></div>
<div class="card-body">
<h3>Product C</h3>
<p>This product's short description is amazing.</p>
</div>
<div class="card-footer">
<span class="card-price">$35.00</span>
<button class="btn-buy">Beli</button>
</div>
</div>
</div>
</body>
</html>
Explanation: The card grid uses flex-wrap: wrap so cards move to a new row. flex: 1 1 280px means the card has a minimum of 280px, can grow to fill the available space, and can shrink. The card body uses flex-direction: column to stack the elements vertically.
3. Holy Grail Layout
<!DOCTYPE html>
<html lang="en">
<head>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
.holy-grail {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.hg-header {
padding: 20px;
background: #1a1a2e;
color: white;
text-align: center;
}
.hg-body {
display: flex;
flex: 1;
}
.hg-sidebar-left {
width: 200px;
padding: 20px;
background: #e2e8f0;
}
.hg-main {
flex: 1;
padding: 20px;
}
.hg-sidebar-right {
width: 200px;
padding: 20px;
background: #e2e8f0;
}
.hg-footer {
padding: 20px;
background: #1a1a2e;
color: white;
text-align: center;
}
</style>
</head>
<body>
<div class="holy-grail">
<header class="hg-header">
<h1>Header</h1>
</header>
<div class="hg-body">
<aside class="hg-sidebar-left">Left Sidebar</aside>
<main class="hg-main">Main Content</main>
<aside class="hg-sidebar-right">Right Sidebar</aside>
</div>
<footer class="hg-footer">
<p>Footer</p>
</footer>
</div>
</body>
</html>
Explanation: The main container uses flex-direction: column to stack the header, body, and footer. The body uses flex-direction: row (the default), with the left sidebar at a fixed width of 200px, main with flex: 1 filling the remaining space, and the right sidebar fixed at 200px.
4. Perfect Centering
<!DOCTYPE html>
<html lang="en">
<head>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
.center-box {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background: linear-gradient(135deg, #667eea, #764ba2);
}
.center-content {
background: white;
padding: 40px;
border-radius: 16px;
text-align: center;
box-shadow: 0 10px 40px rgba(0,0,0,0.2);
}
</style>
</head>
<body>
<div class="center-box">
<div class="center-content">
<h2>Perfectly Centered!</h2>
<p>Horizontal & Vertical Center</p>
</div>
</div>
</body>
</html>
Explanation: Just 3 lines of CSS for perfect centering: display: flex, justify-content: center (horizontal), and align-items: center (vertical). This is one of the biggest advantages of Flexbox.
5. Space Between Footer
<!DOCTYPE html>
<html lang="en">
<head>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
.login-page {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.login-form {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
}
.form-card {
width: 400px;
padding: 30px;
background: white;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0,0,0,0.1);
}
.form-card h2 {
margin-bottom: 20px;
text-align: center;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: 600;
}
.form-group input {
width: 100%;
padding: 10px;
border: 2px solid #e2e8f0;
border-radius: 8px;
font-size: 16px;
}
.form-submit {
width: 100%;
padding: 12px;
background: #667eea;
color: white;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
margin-top: 10px;
}
.login-footer {
padding: 20px;
text-align: center;
color: #94a3b8;
}
</style>
</head>
<body>
<div class="login-page">
<form class="login-form">
<div class="form-card">
<h2>Log In</h2>
<div class="form-group">
<label>Email</label>
<input type="email" placeholder="[email protected]">
</div>
<div class="form-group">
<label>Password</label>
<input type="password" placeholder="Enter password">
</div>
<button type="submit" class="form-submit">Log In</button>
</div>
</form>
<footer class="login-footer">
<p>© 2025 MyBrand. All rights reserved.</p>
</footer>
</div>
</body>
</html>
Explanation: Uses flex-direction: column on the page container. login-form has flex: 1, so it fills all the remaining space and pushes the footer to the bottom. The form card is centered with justify-content: center and align-items: center on the form wrapper.
Conclusion
Flexbox is the most powerful tool for one-dimensional layouts in CSS. The core concepts include:
- Container —
display: flexenables Flexbox - Main axis — Controlled by
flex-directionandjustify-content - Cross axis — Controlled by
align-itemsandalign-self - Item sizing — Controlled by
flex-grow,flex-shrink, andflex-basis - Order — Controlled by
order
Mastering Flexbox will let you solve almost any CSS layout problem more easily and elegantly than with older methods like floats and positioning.