Question
How can I use CSS Flexbox to place numbered elements on separate rows and center each one horizontally within its container? I also want to understand how to center content vertically when the container has a defined height.
<div class="flex-container">
<div class="row"><span class="flex-item">1</span></div>
<div class="row"><span class="flex-item">2</span></div>
<div class="row"><span class="flex-item">3</span></div>
<div class="row"><span class="flex-item">4</span></div>
</div>
.flex-container {
padding: 0;
margin: 0;
list-style: none;
display: flex;
align-items: center;
justify-content: center;
}
.row {
width: 100%;
}
.flex-item {
background: tomato;
padding: 5px;
width: 200px;
height: 150px;
margin: 10px;
line-height: 150px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
}
Short Answer
Flexbox centers flex items, not every nested element automatically. You will learn how the main and cross axes work, how flex-direction changes them, and how to stack items in rows while centering each row’s content.
Concept
A Flexbox layout has two important alignment directions:
- The main axis is controlled by
flex-direction. - The cross axis runs perpendicular to the main axis.
For the default direction, flex-direction: row:
- Main axis: left to right
- Cross axis: top to bottom
justify-contentaligns items left-to-right.align-itemsaligns items top-to-bottom.
Your .flex-container contains four .row elements, so those rows are the direct flex items. With the default row direction, Flexbox attempts to put all four rows beside one another.
To stack the rows vertically, set:
flex-direction: column;
Then each .row still needs its own Flexbox layout to center the .flex-item inside it horizontally. This matters because Flexbox alignment rules apply to a container's direct children. The outer container can align .row elements, while each .row aligns its own .flex-item.
For true vertical centering, the container must have extra vertical space, usually through height or min-height. If a container grows only as tall as its content, there is no unused vertical space in which to center anything.
Mental Model
Think of a Flexbox container as a shelf with two directions for arranging objects:
flex-directiondecides whether the shelf runs across (row) or down (column).justify-contentmoves objects along the shelf.align-itemsmoves objects across the shelf.
A nested Flexbox container is like putting a smaller shelf inside each compartment. The outer shelf positions the rows; each inner shelf positions the numbered box within its row.
Syntax and Examples
The basic Flexbox centering pattern is:
.container {
display: flex;
justify-content: center;
align-items: center;
}
With the default flex-direction: row, this centers direct children horizontally and vertically, provided the container has a height.
To stack direct children vertically and center them:
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
For the numbered-row layout, use a nested Flexbox container:
<div class="flex-container">
<div class="row"><div class="flex-item">1</div></div>
<div class="row"><div class="flex-item">2</div></div>
<div class="row"><div class="flex-item">3</div></div>
<div class="row"><div class="flex-item">4</div></div>
</div>
.flex-container {
display: flex;
flex-direction: column;
}
.row {
display: flex;
justify-content: center;
width: 100%;
}
.flex-item {
width: 200px;
height: 150px;
margin: 10px;
background: tomato;
color: white;
font-size: 3rem;
font-weight: bold;
display: flex;
justify-content: center;
align-items: center;
}
Each .row fills the available width. Its justify-content: center places its direct child, .flex-item, in the horizontal center.
Using a div for .flex-item is convenient because div is block-level. A span is inline by default, so its width and height do not apply as expected unless you set display: inline-block, block, or flex.
Step by Step Execution
Consider this layout:
.flex-container {
display: flex;
flex-direction: column;
min-height: 100vh;
justify-content: center;
}
.row {
display: flex;
justify-content: center;
}
<div class="flex-container">
<div class="row"><div class="flex-item">1</div></div>
<div class="row"><div class="flex-item">2</div></div>
</div>
What happens:
.flex-containerbecomes a Flexbox container.flex-direction: columnmakes its direct children (.row) appear from top to bottom.min-height: 100vhgives the outer container at least the viewport height.- In a column layout, the main axis is vertical, so
justify-content: centermoves the group of rows to the vertical center. - Each
.rowbecomes another Flexbox container. - A row uses the default
flex-direction: row, so its main axis is horizontal. justify-content: centercenters the numbered.flex-itemhorizontally inside that row.
The result is a vertically centered stack of rows, with one horizontally centered item in every row.
Real World Use Cases
Flexbox centering is common in many interfaces:
- Empty states: Center a “No search results” message and action button in a content panel.
- Login pages: Center a sign-in card inside the viewport.
- Loading screens: Center a spinner and status text both horizontally and vertically.
- Dashboards: Put controls or status cards in vertically stacked, centered sections.
- Product cards: Center an icon, title, and price within a card.
- Dialogs and modals: Center the dialog within an overlay.
Real Codebase Usage
In real projects, developers often use Flexbox with clear, reusable layout classes or component styles.
Center a page section
.page-empty-state {
min-height: 60vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 1rem;
}
gap adds consistent spacing between direct flex children without assigning margins to every item.
Center a modal
.modal-overlay {
position: fixed;
inset: 0;
display: flex;
justify-content: center;
align-items: center;
padding: 1rem;
}
Use nested layouts intentionally
A common pattern is:
- Outer container controls the position of sections.
- Inner container controls the content inside each section.
.settings-page {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.settings-section {
display: flex;
justify-content: center;
}
This avoids relying on one parent to align descendants that are not its direct flex items.
Common Mistakes
Forgetting that Flexbox only aligns direct children
This does not center .flex-item within .row:
.flex-container {
display: flex;
justify-content: center;
}
The direct children are .row, not .flex-item. Make .row a flex container too:
.row {
display: flex;
justify-content: center;
}
Using the wrong axis
.container {
display: flex;
flex-direction: column;
align-items: center;
}
This horizontally centers items in a column layout. It does not vertically center the group. Add justify-content: center for vertical centering.
Expecting vertical centering without container height
.container {
display: flex;
justify-content: center;
align-items: center;
}
If the container is only as tall as its content, vertical centering has no visible effect. Give it available space:
.container {
min-height: 100vh;
}
Styling an inline span as though it were a box
span {
width: 200px;
height: 150px;
}
An inline element does not normally honor width and height. Use a block-like display:
span {
display: flex;
}
Or use a div when the element represents a layout box.
Missing the class selector
row {
width: 100%;
}
This targets an HTML element named <row>, not class="row". Use a period for a class:
.row {
width: 100%;
}
Comparisons
| Situation | justify-content controls | align-items controls |
|---|---|---|
flex-direction: row | Horizontal position | Vertical position |
flex-direction: column | Vertical position | Horizontal position |
| Approach | Best for | Limitation |
|---|---|---|
| Flexbox | Aligning items in one dimension or simple two-axis centering | Direct children are the items being aligned |
| CSS Grid | Aligning items in rows and columns | Can be more than needed for a simple one-row layout |
margin: 0 auto | Horizontally centering one fixed or max-width block | Does not vertically center and needs a constrained width |
text-align: center | Centering inline text or inline elements | Does not center block-level layout elements vertically |
For a single centered box, Flexbox is often the clearest choice. For a full two-dimensional dashboard or gallery, CSS Grid may better describe the layout.
Cheat Sheet
/* Horizontal and vertical center in a row layout */
.container {
display: flex;
justify-content: center;
align-items: center;
}
/* Stack children, then center the stack vertically and horizontally */
.container {
display: flex;
flex-direction: column;
justify-content: center; /* vertical in column mode */
align-items: center; /* horizontal in column mode */
min-height: 100vh;
}
/* Center one child inside every full-width row */
.row {
width: 100%;
display: flex;
justify-content: center;
}
/* Make an inline span behave like a sized box */
.flex-item {
display: flex;
justify-content: center;
align-items: center;
}
display: flexactivates Flexbox.justify-contentworks on the main axis.align-itemsworks on the cross axis.flex-directionchanges which physical direction each axis represents.- Alignment affects direct children only.
- Use
heightormin-heightwhen vertical centering needs visible space. - Use
.rowfor a class selector, notrow.
FAQ
How do I center a div both horizontally and vertically with Flexbox?
Set the parent to display: flex, then use justify-content: center and align-items: center. Give the parent a height or min-height if vertical centering should be visible.
Why is justify-content: center not centering my nested element?
It centers only the parent container's direct flex items. If the target is nested inside another element, make that inner parent a Flexbox container as well.
What is the difference between justify-content and align-items?
justify-content aligns along the main axis. align-items aligns along the cross axis. The direction changes when you use flex-direction: column.
How do I put Flexbox items one below another?
Use flex-direction: column on their Flexbox parent.
Why do width and height not work on my span?
A span is inline by default. Set display: inline-block, block, flex, or inline-flex, or use a block element such as div.
Do I need line-height to vertically center text in a box?
No. line-height can work for a single line, but display: flex; align-items: center; justify-content: center; handles single or multiple lines more reliably.
Should I use height: 100vh or min-height: 100vh?
Use min-height: 100vh when content may grow taller than the viewport. It keeps at least viewport height without forcing overflow from larger content.
Mini Project
Description
Build a simple full-screen status page that displays several numbered task cards in a vertical stack. The stack should be centered in the viewport, and every card should center its own text without relying on line-height.
Goal
Create a vertically and horizontally centered stack of responsive task cards using nested Flexbox containers.
Requirements
Include a full-page container with at least the viewport height.
Stack four task cards from top to bottom.
Center the stack within the page vertically and horizontally.
Center the text inside every card.
Use gap for spacing between cards.
Keep learning
Related questions
Angular ngClass Conditional Class Binding Explained
Learn how to use Angular ngClass for conditional classes, fix common binding mistakes, and understand why this template error happens.
Apply CSS to an iframe: Same-Origin Styling in HTML
Learn why parent-page CSS does not style iframe content, how same-origin rules work, and practical ways to style embedded pages safely.
Apply Multiple CSS Transforms: rotate() and translate()
Learn how to combine multiple CSS transform functions such as rotate() and translate(), understand transform order, and avoid overwritten rules.