Understanding the Flexbox Model
CSS Flexbox is a layout model designed for user interface design, optimizing the arrangement of items in one dimension. Unlike previous layout methods that often required workarounds and hacks, Flexbox provides a clean, predictable way to distribute space and align content within a container. The core concept is remarkably simple: you define a container and specify how elements inside that container should behave, controlling their direction, distribution, and alignment with intuitive properties.
This declarative approach eliminates much of the guesswork that plagued older layout techniques, making code more maintainable and layouts more adaptable across different screen sizes. Modern web development relies heavily on Flexbox for creating responsive layouts that work seamlessly across devices, from mobile phones to large desktop monitors. To understand how Flexbox compares with traditional CSS layout approaches, see our guide on Block and Inline Layout in Normal Flow.
Understanding Flexbox is essential for any web developer working with modern CSS techniques. It forms the foundation for many responsive design patterns and pairs excellently with CSS Grid for complex page layouts.
Key Terminology
Understanding Flexbox requires familiarizing yourself with its specific vocabulary:
-
Flex Container: A parent element with
display: flexordisplay: inline-flexapplied. It establishes the flex formatting context for its children. -
Flex Items: The direct children of a flex container. These elements participate in the flex layout and can have their size and position controlled by flexbox properties.
-
Main Axis: The primary axis along which flex items are laid out. By default, this runs horizontally (left to right) but can be changed using the
flex-directionproperty. -
Cross Axis: The axis perpendicular to the main axis. When items flow horizontally, the cross axis runs vertically, and vice versa.
-
Main Start/Main End: The points where flex items begin and end along the main axis, determining the direction of item placement.
-
Cross Start/Cross End: The boundaries of the cross axis where items are aligned.
-
Main Size/Cross Size: The dimensions of a flex item along the main and cross axes respectively.
1.flex-container {2 display: flex;3}4 5.inline-flex-container {6 display: inline-flex;7}8 9.flex-item {10 /* These are the flex items */11}Getting Started with Flex Containers
Creating a Flex Container
To activate flexbox layout, apply display: flex to an element. This single declaration transforms the element into a flex container and its direct children into flex items:
.flex-container {
display: flex;
}
.inline-flex-container {
display: inline-flex;
}
The choice between flex and inline-flex affects only how the container itself behaves in relation to neighboring elements. Both values create identical flex formatting contexts for the container's children.
The flex-direction Property
The flex-direction property establishes the main axis, determining the direction in which flex items are placed:
-
row (default): Items flow left to right in horizontal rows, matching the text direction of the document.
-
row-reverse: Items flow right to left, reversing the visual order without changing the HTML structure.
-
column: Items stack vertically from top to bottom, creating a vertical flow similar to block elements.
-
column-reverse: Items stack from bottom to top, with the first item appearing at the bottom of the container.
Controlling Wrapping with flex-wrap
By default, flex items will shrink to fit their container. The flex-wrap property controls whether items wrap:
-
nowrap (default): All items fit on a single line, potentially shrinking below their natural size.
-
wrap: Items wrap onto multiple lines from top to bottom.
-
wrap-reverse: Items wrap onto multiple lines from bottom to top.
Managing Space with gap
The gap property provides a convenient way to add space between flex items without needing margins on individual items:
.container {
gap: 1rem;
row-gap: 1rem;
column-gap: 1.5rem;
}
1.container {2 /* Row with wrapping */3 flex-direction: row;4 flex-wrap: wrap;5 6 /* Shorthand equivalent */7 flex-flow: row wrap;8 9 /* Space between items */10 gap: 1rem;11}Aligning and Distributing Flex Items
Aligning Along the Main Axis with justify-content
The justify-content property aligns items along the main axis and distributes any remaining space:
-
flex-start (default): Items are packed toward the start of the main axis.
-
flex-end: Items are packed toward the end of the main axis.
-
center: Items are centered along the main axis, with equal space on both sides.
-
space-between: First item at start, last at end, equal space between.
-
space-around: Equal space around each item (half-space at edges).
-
space-evenly: Equal space between all items including ends.
Aligning Along the Cross Axis with align-items
The align-items property controls how items are aligned along the cross axis:
-
stretch (default): Items stretch to fill the container's cross size.
-
flex-start: Items are positioned at the start of the cross axis.
-
flex-end: Items are positioned at the end of the cross axis.
-
center: Items are centered along the cross axis.
-
baseline: Items are aligned by their text baselines.
Aligning Multi-Line Content with align-content
When items wrap onto multiple lines, align-content controls how lines are distributed:
-
flex-start: Lines packed toward the start of the container.
-
flex-end: Lines packed toward the end.
-
center: Lines centered in the container.
-
space-between: First line at start, last at end.
-
stretch (default): Lines stretch to fill remaining space.
Quick reference for flexbox alignment properties
justify-content
Aligns items along the main axis (horizontal when flex-direction is row)
align-items
Aligns items along the cross axis within their line
align-content
Controls distribution of multiple lines when items wrap
gap
Creates consistent space between flex items without margin collapse
align-self
Overrides align-items for individual flex items
order
Controls the visual order of flex items independently from source order
Controlling Flex Item Behavior
The flex-grow Property
The flex-grow property defines how much of the available space an item should occupy:
.item {
flex-grow: 0; /* Default - item does not grow */
flex-grow: 1; /* Item grows equally with others */
flex-grow: 2; /* Item grows twice as much as others */
}
A value of 0 means the item takes only its specified size. A positive value indicates the proportion of available space the item should consume.
The flex-shrink Property
The flex-shrink property defines how items shrink when space is limited:
.item {
flex-shrink: 1; /* Default - item can shrink */
flex-shrink: 0; /* Item will not shrink below its base size */
}
The flex-basis Property
The flex-basis property specifies the initial size before space distribution:
.item {
flex-basis: auto; /* Use the item's width or height */
flex-basis: 200px; /* Fixed initial size */
flex-basis: 50%; /* Percentage of container */
}
The flex Shorthand
Combine all three properties into one concise declaration:
.item {
flex: 0 1 auto; /* grow shrink basis */
flex: 1; /* Equivalent to flex: 1 1 0% */
flex: 0 200px; /* grow shrink basis */
}
Individual Alignment with align-self
The align-self property overrides the container's align-items setting for individual items:
.item {
align-self: flex-start;
align-self: flex-end;
align-self: center;
align-self: stretch;
}
Reordering with order
The order property controls the visual order of flex items:
.item {
order: 0; /* Default - source order */
order: -1; /* Appears before items with order: 0 */
order: 1; /* Appears after items with order: 0 */
}
Remember that order only affects visual presentation, not the underlying DOM order or accessibility order.
Common Use Cases and Patterns
Navigation Bars
Flexbox excels at creating responsive navigation menus. Use justify-content: space-between to position branding on one side and navigation links on the other. This approach is a cornerstone of modern web development services for creating professional, responsive websites.
.nav {
display: flex;
justify-content: space-between;
align-items: center;
}
Card Layouts
Create responsive card grids with wrap and gap properties:
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
}
.card {
flex: 1 1 300px; /* Grow, shrink, minimum 300px */
max-width: 400px;
}
Centering Content
The most celebrated use case for Flexbox is centering content:
.centered {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
Sticky Footers
Keep the footer at the bottom when content is short:
.page {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.content {
flex: 1; /* Takes remaining space */
}
Form Layouts
Flexbox simplifies form styling by aligning labels and inputs:
.form-row {
display: flex;
gap: 1rem;
align-items: center;
}
.form-row input {
flex: 1;
}
Advanced Techniques
Responsive Grids with Media Queries
.grid {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.item {
flex: 1 1 100%; /* Full width by default */
}
@media (min-width: 600px) {
.item {
flex: 1 1 45%; /* Two columns */
}
}
@media (min-width: 900px) {
.item {
flex: 1 1 30%; /* Three columns */
}
}
Equal-Height Columns
Flexbox automatically makes flex items in the same row equal in height, solving a historical CSS challenge:
.columns {
display: flex;
gap: 2rem;
}
.column {
flex: 1; /* Each column takes equal width */
}
Nested Flex Containers
Combine nested containers for complex layouts:
.card {
display: flex;
flex-direction: column;
}
.card-header {
display: flex;
justify-content: space-between;
}
.card-body {
flex: 1; /* Takes remaining space */
}
Holy Grail Layout
The classic header-footer-sidebar layout is elegantly implemented with Flexbox:
.holy-grail {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.holy-grail-body {
display: flex;
flex: 1;
}
.sidebar {
flex: 0 0 200px;
}
.content {
flex: 1;
}
Flexbox pairs excellently with CSS Grid for sophisticated page layouts that require both one-dimensional component layouts and two-dimensional overall structure.
Frequently Asked Questions
Is Flexbox supported in all modern browsers?
Yes, Flexbox is supported by all modern browsers including Chrome, Firefox, Safari, Edge, and Opera. Internet Explorer 11 has limited support with prefixes.
Should I use Flexbox or CSS Grid?
Use Flexbox for one-dimensional layouts (a row OR a column) and Grid for two-dimensional layouts (rows AND columns together). They complement each other and can be used together in your project.
How do I center an element vertically with Flexbox?
Use `display: flex` with `justify-content: center` and `align-items: center` on the parent container. This centers children both horizontally and vertically.
What is the difference between flex-grow and flex-basis?
flex-basis sets the initial size before space distribution, while flex-grow determines how much of the available space an item should consume after growing.
How do I make items wrap to new lines?
Apply `flex-wrap: wrap` to the container. By default, items won't wrap (flex-wrap: nowrap), causing them to shrink to fit.
Can I use negative values with Flexbox properties?
Only the `order` property accepts negative values. Other flex properties like flex-grow, flex-shrink, and flex-basis require non-negative values.