Flexbox in CSS is a layout system designed for arranging items in one direction at a time. That direction can be a row or a column. Flexbox is especially useful for navigation bars, button groups, cards, form controls, side-by-side content, and any layout where items need flexible spacing or alignment.
Before flexbox, developers often used floats, tables, or inline-block tricks for layout. Those methods worked, but they were harder to align, harder to make responsive, and harder to maintain. Flexbox gives CSS a direct way to distribute space, align items, reorder visual layout, and let items grow or shrink inside a container.
Flex Container and Flex Items
Flexbox starts when an element gets display: flex or display: inline-flex. That element becomes the flex container. Its direct children become flex items. Flexbox properties are split between the container and the items, so knowing where to apply a property is important.
.navbar {
display: flex;
}
.navbar a {
padding: 0.75rem 1rem;
}
In this example, .navbar is the flex container and each link inside it is a flex item. The links line up in a row by default because the default flex direction is row.
Main Axis and Cross Axis
Flexbox works with two axes. The main axis follows the flex direction. The cross axis runs perpendicular to it. If the direction is row, the main axis is horizontal and the cross axis is vertical. If the direction is column, the main axis is vertical and the cross axis is horizontal.
| Flex Direction | Main Axis | Cross Axis |
|---|---|---|
| row | left to right | top to bottom |
| row-reverse | right to left | top to bottom |
| column | top to bottom | left to right |
| column-reverse | bottom to top | left to right |
This axis idea explains why justify-content and align-items can appear to change behavior. They do not randomly change. They follow the main axis and cross axis.
flex-direction
The flex-direction property controls the direction of flex items. The default is row. Use column when items should stack vertically but still use flex alignment and spacing.
.sidebar-menu {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
This pattern is useful for vertical menus, mobile navigation, settings panels, and stacked form sections. The gap property adds spacing between items without needing margins on each child.
justify-content
The justify-content property aligns items along the main axis. In a row layout, it controls horizontal distribution. In a column layout, it controls vertical distribution.
.toolbar {
display: flex;
justify-content: space-between;
}
Common values include flex-start, center, flex-end, space-between, space-around, and space-evenly. For a header, space-between is often used to push a logo to one side and navigation to the other.
align-items
The align-items property aligns items along the cross axis. In a row layout, it controls vertical alignment. This is one of the cleanest ways to vertically center content.
.button-row {
display: flex;
align-items: center;
gap: 1rem;
}
This aligns all buttons, icons, and labels along the center of the row. Values such as stretch, flex-start, center, flex-end, and baseline are commonly used.
gap in Flexbox
The gap property creates space between flex items. It is usually better than adding margin to every item because it keeps spacing controlled by the parent container.
.card-actions {
display: flex;
gap: 0.75rem;
}
Gap works for rows and columns. It also avoids common margin problems, such as removing the last item margin or dealing with collapsed margins in nearby blocks.
flex-wrap
By default, flex items try to stay on one line. The flex-wrap property allows them to move to the next line when there is not enough space.
.tag-list {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
This is useful for tags, chips, filter buttons, and responsive groups. Items stay in a row when space is available and wrap naturally on smaller screens.
flex-grow, flex-shrink and flex-basis
Flex items can grow, shrink, and start from a preferred size. These behaviors are controlled by flex-grow, flex-shrink, and flex-basis. Most real projects use the shorthand flex.
.main-content {
flex: 1 1 auto;
}
.sidebar {
flex: 0 0 280px;
}
The main content can grow and shrink. The sidebar starts at 280px and does not grow. This creates a common page layout where the main area takes remaining space.
Common flex Shorthand Values
| Value | Meaning |
|---|---|
| flex: 1 | item can grow and share available space |
| flex: 0 0 auto | item keeps its natural size |
| flex: 0 0 250px | fixed basis of 250px |
| flex: 1 1 0 | items distribute space evenly |
The shorthand is powerful, but it should be used deliberately. If an item is shrinking too much, check its flex-shrink value, minimum width, and content size.
Responsive Flex Layout
Flexbox works well with media queries. A desktop row can become a mobile column without changing the HTML structure.
.feature-row {
display: flex;
gap: 2rem;
}
@media (max-width: 700px) {
.feature-row {
flex-direction: column;
}
}
This pattern is common for landing pages, product sections, article cards, and dashboard panels. The layout changes based on available width while the content order stays logical.
Flexbox vs Grid
Flexbox is best for one-dimensional layouts. CSS Grid is best for two-dimensional layouts. If the main concern is a row or a column, flexbox is usually a good choice. If the layout needs rows and columns at the same time, grid is usually better.
| Need | Better Choice |
|---|---|
| Navigation bar | Flexbox |
| Button group | Flexbox |
| Equal card grid | Grid |
| Full page layout | Grid |
| Card content alignment | Flexbox |
order Property
The order property changes the visual order of flex items without changing the HTML order. By default, every flex item has order: 0. Items with lower order values appear first, and items with higher values appear later.
.featured-link {
order: -1;
}
.secondary-action {
order: 2;
}
This can be useful for small responsive changes, such as moving a button before text on mobile. Use it carefully because screen readers and keyboard navigation still follow the HTML order. If the visual order becomes very different from the source order, the page can become confusing for assistive technology users.
align-self
The align-self property lets one flex item override the container alignment. If the container uses align-items: center, one child can still align to the start or end.
.card {
display: flex;
align-items: center;
}
.card-badge {
align-self: flex-start;
}
This is useful for badges, icons, labels, and small controls that need a different vertical position from the rest of the row. It avoids creating a completely separate layout just for one item.
Nested Flexbox
Flexbox layouts are often nested. A page section may use flexbox to place an image beside text, while the text area uses another flex container to align buttons, metadata, or icons. This is normal and usually clean when each flex container has a clear purpose.
.profile-card {
display: flex;
gap: 1.5rem;
}
.profile-actions {
display: flex;
gap: 0.75rem;
flex-wrap: wrap;
}
The outer flex container handles the main card structure. The inner flex container handles only the action buttons. Keeping responsibilities separate makes the CSS easier to reason about.
Real Flexbox Example: Header Navigation
A header is a classic flexbox use case because the layout is mostly one-dimensional. The logo, menu, and action button need to sit in one row on desktop. Flexbox can align them vertically and distribute space without floats.
.site-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
}
.site-menu {
display: flex;
gap: 1rem;
flex-wrap: wrap;
}
The header controls the large relationship between the logo and navigation. The menu controls spacing between links. On mobile, the menu can switch to a column or be moved into an off-canvas panel, while the header still keeps its internal alignment clean.
This is why flexbox is so common in UI components. It solves the alignment and spacing problem directly, without requiring each item to know about the margins of every other item.
min-width: 0 Problem
Sometimes a flex item refuses to shrink and causes horizontal overflow. This often happens when the item contains long text, code, URLs, or tables. The fix is often min-width: 0 on the flex item.
.content {
flex: 1;
min-width: 0;
}
Flex items have an automatic minimum size based on their content. Setting min-width: 0 allows the item to shrink inside the available space. This small rule fixes many real responsive bugs.
When debugging flexbox, resize the browser slowly and watch which item breaks first. The problem is usually missing wrapping, a child that cannot shrink, or spacing that should be handled with gap instead of margins.
Also check whether a child has a fixed width that no longer fits the container. Flexible layout still needs sensible minimum and maximum sizes.
Good flexbox code should adapt without needing fragile width calculations.
A Practical Flexbox Checklist
- Set display: flex on the parent, not the child.
- Decide the main axis with flex-direction.
- Use gap for spacing between items.
- Use justify-content for main-axis distribution.
- Use align-items for cross-axis alignment.
- Use flex-wrap when items should move to a new line.
- Check min-width when content causes overflow.
Common Flexbox Mistakes
- Applying flex item properties to the container instead of the child.
- Forgetting that justify-content follows the main axis.
- Using flexbox for complex two-dimensional grids.
- Using margins for spacing when gap would be cleaner.
- Expecting flex-wrap without setting flex-wrap: wrap.
- Ignoring minimum content size when items refuse to shrink.
Flexbox in CSS FAQ
What is flexbox in CSS?
Flexbox is a CSS layout system for arranging items in a row or column with flexible spacing and alignment.
When should I use flexbox?
Use flexbox for one-dimensional layouts such as navigation bars, button groups, aligned cards, and responsive rows or columns.
What is the difference between justify-content and align-items?
justify-content works on the main axis, while align-items works on the cross axis.
Should I use flexbox or grid?
Use flexbox for one direction at a time and grid for rows and columns together.
Continue learning CSS in order
Follow the topic sequence with the previous and next lesson.