Flexbox Container Properties
Introduction to Flexbox
CSS Flexible Box Layout, commonly known as Flexbox, is a one-dimensional layout system designed to distribute space among items in a container and align them efficiently, even when their sizes are unknown or dynamic. Before Flexbox, developers relied on floats, table-based layouts, and inline-block hacks to build common UI patterns like navigation bars, centered content, equally spaced items, and flexible card layouts. These older techniques were cumbersome, fragile, and often required counter-intuitive workarounds. Flexbox was created specifically to solve these problems with a clean, predictable, and powerful set of properties.
Flexbox is called a "one-dimensional" layout system because it handles layout in one direction at a time -- either as a row (horizontal) or as a column (vertical). This distinguishes it from CSS Grid, which is a two-dimensional layout system handling both rows and columns simultaneously. While this might sound limiting, one-dimensional control is exactly what you need for the vast majority of layout tasks: navigation menus, toolbars, form controls, card rows, footer links, centering content, and distributing space between elements.
In this lesson, we will focus exclusively on the Flexbox container properties -- the properties you apply to the parent element that holds flex items. Understanding the container properties is the foundation of Flexbox mastery. In the next lesson, we will cover the flex item properties that control individual children within the container.
Creating a Flex Container
To activate Flexbox, you set the display property of a container element to either flex or inline-flex. This single declaration transforms the element into a flex container and all of its direct children into flex items.
display: flex vs display: inline-flex
/* Block-level flex container (takes full width) */
.container {
display: flex;
}
/* Inline-level flex container (only as wide as its content) */
.inline-container {
display: inline-flex;
}
/* HTML structure */
<div class="container">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
</div>
display: flex
When you set display: flex, the container becomes a block-level element. It takes up the full available width of its parent, just like a regular <div>. However, its children are now flex items and are laid out according to Flexbox rules instead of the normal document flow. By default, flex items are arranged in a horizontal row, aligned to the start of the container, and sized according to their content.
display: inline-flex
The display: inline-flex value creates a flex container that behaves like an inline element externally -- it only takes up as much width as its flex items need, and other inline content can sit beside it. Internally, its children are still flex items and follow all Flexbox rules. This is useful when you want a flex container to sit inline with other text or elements, such as a group of buttons within a paragraph or a set of inline tags.
Comparing flex and inline-flex
<!-- Block-level: takes full width -->
<div class="flex-container">
<span>A</span>
<span>B</span>
<span>C</span>
</div>
<p>This paragraph starts on a new line.</p>
<!-- Inline-level: sits inline with surrounding content -->
<p>
Here are some tags:
<span class="inline-flex-container">
<span class="tag">CSS</span>
<span class="tag">HTML</span>
<span class="tag">JS</span>
</span>
and they sit inline with the text.
</p>
float and clear properties have no effect on flex items. The vertical-align property also has no effect on flex items. However, flex items can still be absolutely positioned, in which case they are removed from the flex layout.Understanding the Flex Axes
Flexbox layout is based on two axes that define how items are arranged and aligned. Understanding these axes is absolutely critical to mastering Flexbox because every alignment and distribution property references one of these axes.
The Main Axis
The main axis is the primary axis along which flex items are laid out. By default, the main axis runs horizontally from left to right (in left-to-right languages). Flex items are placed one after another along this axis. The flex-direction property determines the direction of the main axis. The start of the main axis is called main-start and the end is called main-end.
The Cross Axis
The cross axis is perpendicular to the main axis. If the main axis is horizontal, the cross axis is vertical (and vice versa). The cross axis determines how items are aligned in the perpendicular direction. The start of the cross axis is called cross-start and the end is called cross-end.
Visualizing the Axes
/* Default: main axis is horizontal (row) */
/*
main-start ───── Main Axis ────> main-end
│
│ cross-start
│
▼ Cross Axis
│
│ cross-end
*/
/* When flex-direction: column */
/*
cross-start ──── Cross Axis ───> cross-end
│
│ main-start
│
▼ Main Axis
│
│ main-end
*/
justify-content always works along the main axis. align-items and align-content always work along the cross axis.flex-direction
The flex-direction property defines the direction of the main axis, which in turn determines the direction in which flex items are placed inside the container. It accepts four values, each establishing a different main axis direction.
All flex-direction Values
/* Items flow left to right (default) */
.row {
display: flex;
flex-direction: row;
}
/* Items flow right to left */
.row-reverse {
display: flex;
flex-direction: row-reverse;
}
/* Items flow top to bottom */
.column {
display: flex;
flex-direction: column;
}
/* Items flow bottom to top */
.column-reverse {
display: flex;
flex-direction: column-reverse;
}
flex-direction: row (Default)
This is the default value. The main axis runs horizontally, and items are placed from left to right (in LTR languages) or right to left (in RTL languages like Arabic). Items are arranged in a single horizontal line, each one placed after the previous one along the main axis. The cross axis runs vertically.
flex-direction: row-reverse
The main axis still runs horizontally, but the direction is reversed. Items are placed from right to left (in LTR languages). This does not simply apply a visual reversal -- the main-start and main-end points are swapped, which means properties like justify-content: flex-start will push items to the right instead of the left. This can be useful for reversing the visual order of items without changing the HTML source order.
flex-direction: column
The main axis runs vertically from top to bottom. Items are stacked on top of each other, similar to normal block elements, but with the full power of Flexbox alignment and distribution. When using flex-direction: column, properties like justify-content control vertical distribution, and align-items controls horizontal alignment -- the opposite of the default row direction.
flex-direction: column-reverse
The main axis runs vertically from bottom to top. Items are stacked in reverse order, with the first item at the bottom and the last item at the top. This is useful for chat interfaces, timelines displayed in reverse, or any layout where you want content to flow upward.
Practical Example: Direction Changes
<div class="nav-horizontal">
<a href="#">Home</a>
<a href="#">About</a>
<a href="#">Services</a>
<a href="#">Contact</a>
</div>
<div class="sidebar-vertical">
<a href="#">Dashboard</a>
<a href="#">Settings</a>
<a href="#">Profile</a>
<a href="#">Logout</a>
</div>
CSS for Direction Examples
.nav-horizontal {
display: flex;
flex-direction: row;
gap: 20px;
padding: 10px 20px;
background: #2c3e50;
}
.nav-horizontal a {
color: white;
text-decoration: none;
padding: 8px 16px;
}
.sidebar-vertical {
display: flex;
flex-direction: column;
width: 200px;
background: #34495e;
}
.sidebar-vertical a {
color: white;
text-decoration: none;
padding: 12px 20px;
border-bottom: 1px solid #4a6785;
}
row-reverse or column-reverse only changes the visual order of items, not the document order. Screen readers and keyboard navigation still follow the original HTML source order. If the visual order is important for comprehension, changing the source order is usually a better approach than using reverse directions, as it ensures accessibility is maintained.flex-wrap
By default, flex items try to fit on a single line. If the combined width of all items exceeds the container's width, the items will shrink to fit (if their flex-shrink value allows it) rather than wrapping to a new line. The flex-wrap property controls whether flex items are forced onto a single line or can wrap onto multiple lines.
flex-wrap Values
/* All items forced on one line (default) */
.no-wrap {
display: flex;
flex-wrap: nowrap;
}
/* Items wrap to new lines as needed */
.wrap {
display: flex;
flex-wrap: wrap;
}
/* Items wrap in reverse order */
.wrap-reverse {
display: flex;
flex-wrap: wrap-reverse;
}
flex-wrap: nowrap (Default)
This is the default value. All flex items are placed on a single line, and they will shrink if necessary to avoid overflowing the container. If items have a fixed minimum width that prevents them from shrinking enough, they will overflow the container. This behavior is useful when you want all items to remain visible in a single row or column, such as a navigation bar.
flex-wrap: wrap
When wrapping is enabled, flex items that do not fit on the current line will move to the next line. In a row layout, this means items wrap to a new row below. In a column layout, items wrap to a new column to the right (in LTR). Each new line of wrapped items is called a flex line. The align-content property (covered later in this lesson) controls how multiple flex lines are distributed along the cross axis.
flex-wrap: wrap-reverse
This works like wrap, but new lines are added in the opposite direction. In a row layout, items wrap to a new row above instead of below. This can be useful for specific design patterns where you want the most recent items to appear at the top.
Practical Example: Wrapping Card Layout
.card-container {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.card {
flex: 1 1 300px;
/* flex-grow: 1 -- cards grow to fill space
flex-shrink: 1 -- cards can shrink
flex-basis: 300px -- ideal width is 300px */
padding: 20px;
background: var(--bg-white);
border: 1px solid var(--border-light);
border-radius: 8px;
}
/* On a 1000px container:
3 cards fit in first row (300px each + gaps)
Remaining cards wrap to next row */
flex-wrap: wrap is active and items wrap to multiple lines, the container's cross size grows to accommodate all the flex lines. Each flex line is independently sized based on the tallest item in that line. The align-content property controls the spacing between these flex lines.The flex-flow Shorthand
The flex-flow property is a shorthand that combines flex-direction and flex-wrap into a single declaration. This reduces the amount of CSS you need to write and makes it easy to see both the direction and wrapping behavior at a glance.
flex-flow Shorthand Examples
/* Row direction, no wrapping (default) */
.default {
flex-flow: row nowrap;
}
/* Row direction with wrapping */
.row-wrap {
flex-flow: row wrap;
}
/* Column direction, no wrapping */
.column-no-wrap {
flex-flow: column nowrap;
}
/* Column direction with wrapping */
.column-wrap {
flex-flow: column wrap;
}
/* Reversed row with wrapping */
.row-reverse-wrap {
flex-flow: row-reverse wrap;
}
/* Single value: sets direction, wrap defaults to nowrap */
.just-direction {
flex-flow: column;
}
/* Single value: sets wrap, direction defaults to row */
.just-wrap {
flex-flow: wrap;
}
justify-content
The justify-content property controls how flex items are distributed along the main axis. It determines what happens to the extra space when flex items do not fill the entire main axis of the container. This is one of the most frequently used Flexbox properties, and understanding each of its values is essential.
All justify-content Values
/* Items packed at the start of the main axis (default) */
.start {
display: flex;
justify-content: flex-start;
}
/* Items packed at the end of the main axis */
.end {
display: flex;
justify-content: flex-end;
}
/* Items centered along the main axis */
.center {
display: flex;
justify-content: center;
}
/* Equal space between items, no space at edges */
.between {
display: flex;
justify-content: space-between;
}
/* Equal space around each item */
.around {
display: flex;
justify-content: space-around;
}
/* Equal space between and around items */
.evenly {
display: flex;
justify-content: space-evenly;
}
justify-content: flex-start (Default)
Items are packed toward the start of the main axis. In a left-to-right row layout, items align to the left edge. Any extra space appears on the right side (the end of the main axis). This is the default behavior and matches what you see when you first set display: flex without specifying any alignment.
justify-content: flex-end
Items are packed toward the end of the main axis. In a left-to-right row layout, items align to the right edge. Any extra space appears on the left side. This is useful for pushing items like buttons or navigation links to the right side of a container without using margin-left: auto tricks.
justify-content: center
Items are centered along the main axis. Equal space is placed on both sides of the group of items. This is one of the most common uses of Flexbox -- centering content horizontally (in row direction) or vertically (in column direction). Before Flexbox, horizontal centering was straightforward with margin: 0 auto, but vertical centering required hacky solutions. With Flexbox, both are trivial.
justify-content: space-between
Items are evenly distributed along the main axis. The first item is flush against the start edge, the last item is flush against the end edge, and equal space is placed between each pair of adjacent items. There is no space before the first item or after the last item. This is perfect for navigation bars where you want items spread across the full width with the first and last items touching the edges.
justify-content: space-around
Items are evenly distributed with equal space around each item. This means the space before the first item and after the last item is half the size of the space between adjacent items. If the space between two adjacent items is 20px, the space at each edge is 10px. This creates a visually balanced distribution but with less space at the edges.
justify-content: space-evenly
Items are evenly distributed with exactly equal space between every pair of adjacent items AND between the items and the container edges. Every gap is identical. This produces the most uniform spacing. If there is 60px of total extra space and 3 items, each of the 4 gaps (before item 1, between items 1-2, between items 2-3, and after item 3) gets exactly 15px.
Visual Comparison of justify-content Values
/* Assume 3 items, each 100px wide, in a 500px container */
/* 200px of extra space to distribute */
/* flex-start: [A][B][C].................. */
/* flex-end: ..................[A][B][C] */
/* center: .........[A][B][C]......... */
/* space-between: [A]........[B]........[C] */
/* space-around: ..[A]......[B]......[C].. */
/* space-evenly: ....[A]....[B]....[C].... */
Practical Example: Navigation Bar with justify-content
<nav class="navbar">
<div class="logo">MyBrand</div>
<ul class="nav-links">
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Services</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
CSS for Navigation Bar
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 30px;
background: #2c3e50;
color: white;
}
.logo {
font-size: 24px;
font-weight: bold;
}
.nav-links {
display: flex;
gap: 25px;
list-style: none;
margin: 0;
padding: 0;
}
.nav-links a {
color: white;
text-decoration: none;
padding: 8px 12px;
border-radius: 4px;
transition: background 0.3s;
}
.nav-links a:hover {
background: rgba(255, 255, 255, 0.1);
}
align-items
While justify-content distributes items along the main axis, align-items controls how items are aligned along the cross axis. In a default row layout, the cross axis runs vertically, so align-items controls vertical alignment. In a column layout, it controls horizontal alignment.
All align-items Values
/* Items stretch to fill the cross axis (default) */
.stretch {
display: flex;
align-items: stretch;
}
/* Items aligned to the start of the cross axis */
.start {
display: flex;
align-items: flex-start;
}
/* Items aligned to the end of the cross axis */
.end {
display: flex;
align-items: flex-end;
}
/* Items centered along the cross axis */
.center {
display: flex;
align-items: center;
}
/* Items aligned by their text baselines */
.baseline {
display: flex;
align-items: baseline;
}
align-items: stretch (Default)
This is the default value. Flex items stretch to fill the entire cross axis of the container (as long as they do not have an explicit height or width set on the cross dimension). In a row layout, all items stretch to the height of the tallest item. In a column layout, items stretch to the width of the widest item. This is why flex items often appear to have equal heights without any extra CSS -- it is the default align-items: stretch behavior at work.
align-items: flex-start
Items are aligned to the start of the cross axis. In a row layout, items are pushed to the top. Each item is only as tall as its content requires -- there is no stretching. This is useful when you want items to maintain their natural height rather than stretching to match the tallest sibling.
align-items: flex-end
Items are aligned to the end of the cross axis. In a row layout, items are pushed to the bottom. This is useful for aligning items like prices or action buttons at the bottom of a container, especially when sibling items have different content heights.
align-items: center
Items are centered along the cross axis. In a row layout, items are vertically centered. Combined with justify-content: center, this creates the famous "perfect centering" pattern that was notoriously difficult to achieve before Flexbox.
The Famous Perfect Centering Pattern
/* Center anything both horizontally and vertically */
.perfect-center {
display: flex;
justify-content: center; /* Center on main axis (horizontal) */
align-items: center; /* Center on cross axis (vertical) */
min-height: 100vh; /* Full viewport height */
}
/* The child will be perfectly centered in the viewport */
.perfect-center .content {
max-width: 600px;
padding: 40px;
background: var(--bg-white);
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}
align-items: baseline
Items are aligned so that their text baselines line up. This is particularly useful when you have items with different font sizes or padding, and you want the text in each item to sit on the same horizontal line. The baseline is the invisible line on which most letters "sit" -- the bottom of letters like "a", "b", "c" but not the descenders of letters like "g", "p", "y".
Baseline Alignment Example
<div class="baseline-demo">
<div class="small-text">Small text</div>
<div class="large-text">Large text</div>
<div class="padded-text">Padded text</div>
</div>
CSS for Baseline Demo
.baseline-demo {
display: flex;
align-items: baseline;
gap: 20px;
padding: 20px;
background: #f8f9fa;
border: 2px dashed #ddd;
}
.small-text {
font-size: 14px;
padding: 5px 10px;
background: #3498db;
color: white;
}
.large-text {
font-size: 32px;
padding: 10px 20px;
background: #e74c3c;
color: white;
}
.padded-text {
font-size: 18px;
padding: 30px 15px;
background: #2ecc71;
color: white;
}
/* Despite different font sizes and padding,
the text in all three items aligns on the
same baseline */
align-items: baseline whenever you have navigation links, breadcrumbs, or inline elements with different font sizes that need to look visually aligned. It produces a much more polished result than flex-start or center in these situations.align-content
The align-content property controls how multiple flex lines are distributed along the cross axis. This property only takes effect when flex-wrap is set to wrap or wrap-reverse and there are multiple lines of items. If all items fit on a single line, align-content has no effect.
Think of align-content as the cross-axis equivalent of justify-content. While justify-content distributes items along the main axis, align-content distributes flex lines along the cross axis. And while align-items aligns individual items within a single flex line, align-content aligns the lines themselves within the container.
All align-content Values
/* Lines stretch to fill the cross axis (default) */
.stretch {
display: flex;
flex-wrap: wrap;
align-content: stretch;
}
/* Lines packed at the start of the cross axis */
.start {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
}
/* Lines packed at the end of the cross axis */
.end {
display: flex;
flex-wrap: wrap;
align-content: flex-end;
}
/* Lines centered along the cross axis */
.center {
display: flex;
flex-wrap: wrap;
align-content: center;
}
/* Equal space between lines */
.between {
display: flex;
flex-wrap: wrap;
align-content: space-between;
}
/* Equal space around each line */
.around {
display: flex;
flex-wrap: wrap;
align-content: space-around;
}
/* Equal space between and around lines */
.evenly {
display: flex;
flex-wrap: wrap;
align-content: space-evenly;
}
Practical Example: align-content with Wrapped Items
.wrapped-grid {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
height: 500px;
gap: 15px;
padding: 15px;
background: #f0f0f0;
}
.wrapped-grid .item {
flex: 0 0 calc(33.333% - 10px);
padding: 20px;
background: var(--bg-white);
border: 1px solid var(--border-light);
border-radius: 8px;
text-align: center;
}
/* With align-content: flex-start, the wrapped rows
are packed at the top, with extra space at the bottom.
With align-content: center, the rows would be
vertically centered within the 500px container. */
align-content when items are on a single line (no wrapping). Remember: align-content only works when there are multiple flex lines. For single-line containers, use align-items instead. If you set flex-wrap: wrap but all items fit on one line, align-content will still have no visible effect.gap, row-gap, and column-gap
The gap property (and its sub-properties row-gap and column-gap) adds consistent spacing between flex items without using margins. This is one of the most practical additions to Flexbox, as it eliminates the common problem of needing to remove margins from the first or last item in a row.
Using gap in Flexbox
/* Uniform gap between all items */
.uniform-gap {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
/* Different row and column gaps */
.different-gaps {
display: flex;
flex-wrap: wrap;
row-gap: 30px;
column-gap: 15px;
}
/* Shorthand: row-gap then column-gap */
.shorthand-gap {
display: flex;
flex-wrap: wrap;
gap: 30px 15px;
/* row-gap: 30px, column-gap: 15px */
}
/* Compare with the old margin approach */
.old-approach .item {
margin: 0 10px 10px 0;
}
/* Problem: last item in row has unwanted right margin */
/* Problem: last row has unwanted bottom margin */
/* gap approach -- no such problems! */
.new-approach {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
/* gap only adds space BETWEEN items, never at the edges */
Practical Example: Tag Cloud with gap
.tag-cloud {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.tag {
padding: 6px 14px;
background: var(--bg-light);
border: 1px solid var(--border-light);
border-radius: 20px;
font-size: 14px;
color: var(--text-dark);
transition: all 0.2s;
}
.tag:hover {
background: var(--primary);
color: white;
border-color: var(--primary);
}
gap property in Flexbox has excellent browser support in all modern browsers. It was originally only available in CSS Grid, but was later extended to Flexbox. If you need to support very old browsers (Internet Explorer or Safari versions before 14.1), you may need to use the margin approach as a fallback.Nested Flex Containers
One of the most powerful aspects of Flexbox is that flex items can themselves be flex containers. This nesting allows you to build complex layouts by combining multiple flex containers, each controlling the alignment and distribution of its own children independently.
Nested Flexbox Example: Header Layout
<header class="site-header">
<div class="header-left">
<img src="logo.svg" alt="Logo" class="logo">
<span class="brand-name">MyCompany</span>
</div>
<nav class="header-center">
<a href="#">Products</a>
<a href="#">Pricing</a>
<a href="#">Docs</a>
<a href="#">Blog</a>
</nav>
<div class="header-right">
<button class="btn-login">Log In</button>
<button class="btn-signup">Sign Up</button>
</div>
</header>
CSS for Nested Header
/* Outer flex container: distributes three sections */
.site-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 30px;
background: white;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
}
/* Inner flex container: logo + brand name */
.header-left {
display: flex;
align-items: center;
gap: 10px;
}
.logo {
width: 32px;
height: 32px;
}
.brand-name {
font-size: 20px;
font-weight: 700;
color: var(--text-dark);
}
/* Inner flex container: navigation links */
.header-center {
display: flex;
gap: 30px;
}
.header-center a {
color: var(--text-dark);
text-decoration: none;
font-weight: 500;
padding: 8px 0;
position: relative;
}
.header-center a::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 2px;
background: var(--primary);
transition: width 0.3s;
}
.header-center a:hover::after {
width: 100%;
}
/* Inner flex container: auth buttons */
.header-right {
display: flex;
align-items: center;
gap: 12px;
}
.btn-login {
padding: 8px 20px;
background: transparent;
border: 1px solid var(--border-light);
border-radius: 6px;
cursor: pointer;
}
.btn-signup {
padding: 8px 20px;
background: var(--primary);
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
}
Comprehensive Practical Examples
Example 1: Holy Grail Layout
Classic Three-Column Page Layout
<div class="page-layout">
<header class="page-header">Header</header>
<div class="page-body">
<aside class="sidebar-left">Left Sidebar</aside>
<main class="main-content">Main Content</main>
<aside class="sidebar-right">Right Sidebar</aside>
</div>
<footer class="page-footer">Footer</footer>
</div>
CSS for Holy Grail Layout
.page-layout {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.page-header, .page-footer {
padding: 20px;
background: #2c3e50;
color: white;
text-align: center;
}
.page-body {
display: flex;
flex: 1;
}
.sidebar-left {
flex: 0 0 200px;
padding: 20px;
background: #ecf0f1;
}
.main-content {
flex: 1;
padding: 20px;
}
.sidebar-right {
flex: 0 0 250px;
padding: 20px;
background: #ecf0f1;
}
/* Responsive: stack on mobile */
@media (max-width: 768px) {
.page-body {
flex-direction: column;
}
.sidebar-left,
.sidebar-right {
flex: none;
}
}
Example 2: Centered Login Card
Perfect Centering with Flexbox
.login-page {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 20px;
}
.login-card {
display: flex;
flex-direction: column;
gap: 20px;
width: 100%;
max-width: 400px;
padding: 40px;
background: white;
border-radius: 16px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}
.login-card h2 {
text-align: center;
margin: 0;
color: var(--text-dark);
}
.login-card input {
padding: 12px 16px;
border: 1px solid var(--border-light);
border-radius: 8px;
font-size: 16px;
}
.login-card button {
padding: 14px;
background: var(--primary);
color: white;
border: none;
border-radius: 8px;
font-size: 16px;
cursor: pointer;
}
.login-card .links {
display: flex;
justify-content: space-between;
font-size: 14px;
}
Example 3: Feature Grid with Wrapping
Responsive Feature Cards
.features {
display: flex;
flex-wrap: wrap;
gap: 24px;
padding: 40px 20px;
}
.feature-card {
flex: 1 1 280px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding: 30px 20px;
background: var(--bg-white);
border-radius: 12px;
border: 1px solid var(--border-light);
transition: transform 0.3s, box-shadow 0.3s;
}
.feature-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.feature-icon {
width: 60px;
height: 60px;
display: flex;
justify-content: center;
align-items: center;
background: var(--primary-light);
border-radius: 50%;
margin-bottom: 16px;
font-size: 28px;
}
.feature-card h3 {
margin: 0 0 10px;
color: var(--text-dark);
}
.feature-card p {
margin: 0;
color: var(--text-light);
line-height: 1.6;
}
Example 4: Footer with Multiple Sections
Flexible Footer Layout
.site-footer {
display: flex;
flex-wrap: wrap;
gap: 40px;
padding: 60px 40px 40px;
background: #1a1a2e;
color: #ccc;
}
.footer-section {
flex: 1 1 200px;
}
.footer-section h4 {
color: white;
margin-bottom: 20px;
font-size: 18px;
}
.footer-section ul {
list-style: none;
padding: 0;
margin: 0;
}
.footer-section li {
margin-bottom: 10px;
}
.footer-section a {
color: #999;
text-decoration: none;
transition: color 0.2s;
}
.footer-section a:hover {
color: white;
}
.footer-bottom {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 20px;
width: 100%;
padding-top: 30px;
border-top: 1px solid #333;
margin-top: 20px;
}
.social-links {
display: flex;
gap: 15px;
}
@media (max-width: 600px) {
.site-footer {
padding: 40px 20px 20px;
}
.footer-bottom {
justify-content: center;
text-align: center;
}
}
justify-content: space-between on the outer container and nested flex containers for the button group. Make it responsive: on mobile, switch to flex-direction: column with centered items and a hamburger menu concept (you can use a checkbox toggle). Ensure the navigation links have even spacing using the gap property.flex: 1 1 250px). Inside each card, use a nested flex column layout to push the price and "Add to Cart" button to the bottom, regardless of how much description text the card has. Use align-items and justify-content to center the product image. Test with different numbers of cards (1, 2, 3, 5, 7) and ensure the layout looks good in all cases.justify-content: space-between for logo and navigation. The middle section should use a row flex container with a fixed-width sidebar and a flexible main area. The footer should have four columns that wrap on smaller screens. Use align-items, justify-content, flex-wrap, flex-direction, gap, and nested flex containers. Make the entire layout fully responsive with at least two breakpoints (tablet and mobile).Summary
Flexbox is a one-dimensional layout system that provides powerful tools for distributing space and aligning items within a container. By setting display: flex or display: inline-flex, you create a flex container whose direct children become flex items. The flex-direction property controls the main axis direction (row, row-reverse, column, column-reverse), and flex-wrap determines whether items can wrap to multiple lines. The flex-flow shorthand combines both. The justify-content property distributes items along the main axis with options like flex-start, flex-end, center, space-between, space-around, and space-evenly. The align-items property aligns items along the cross axis with options including stretch, flex-start, flex-end, center, and baseline. The align-content property controls the distribution of multiple flex lines when wrapping is enabled. The gap property provides clean spacing between items without the complications of margins. By nesting flex containers, you can build sophisticated layouts that are both flexible and maintainable. Understanding these container properties is the foundation of Flexbox -- in the next lesson, we will explore the item properties that give you even more control over individual flex children.