By WebNest Studio Engineering Team
CSS Tutorial
CSS Flexbox
Flexbox (the Flexible Box Layout module) is a one-dimensional layout system designed to distribute space and align items along a single axis — either a row or a column — inside a container. It replaced older, hackier techniques like floats and inline-block for common layout tasks such as navigation bars, centering content, and evenly spacing items.
Flexbox works through a parent/child relationship: you turn an element into a "flex container" with display: flex, and its direct children automatically become "flex items" that respond to a specific set of alignment and sizing properties.
Why it matters
Flexbox made the layouts that used to need hacks straightforward: a row of items with space between them, vertical centring, columns of equal height. Navigation bars, toolbars, cards and form rows are almost always flex containers. It is the layout tool you will use most often.
Flex Container Properties
These properties are set on the parent element to control the overall layout of its children.
- flex-direction — sets the main axis: row (default, left-to-right), column, row-reverse, or column-reverse.
- justify-content — aligns items along the main axis: flex-start, flex-end, center, space-between, space-around, or space-evenly.
- align-items — aligns items along the cross axis (perpendicular to the main axis): flex-start, flex-end, center, stretch (default), or baseline.
- flex-wrap — controls whether items wrap onto multiple lines (wrap) or are forced onto one line and potentially overflow (nowrap, the default).
Flex Item Properties
These properties are set on the children to control how each individual item grows, shrinks, and sizes itself relative to its siblings.
- flex-grow — a unitless number defining how much of the remaining free space an item should consume relative to its siblings; 0 (default) means it won't grow.
- flex-shrink — defines how much an item should shrink relative to siblings when there isn't enough space; 1 is the default, 0 prevents shrinking.
- flex-basis — sets the item's initial size before growing or shrinking is calculated, similar to width but flex-aware.
- flex shorthand — combines all three:
flex: 1 1 0;is a common pattern meaning "grow and shrink equally from a zero base," producing evenly sized items.
Examples
A navigation bar centered vertically with space between links
<!--
<nav class="navbar">
<span class="logo">Brand</span>
<div class="links"><a href="#">Home</a><a href="#">About</a></div>
</nav>
-->
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
}
The logo sits at the far left and the links group sits at the far right, both vertically centered within the navbar regardless of their differing heights.
Three equally sized columns that grow and shrink together
.row {
display: flex;
gap: 1rem;
}
.column {
flex: 1 1 0; /* grow equally, shrink equally, start from zero basis */
}
The three columns split the available width evenly, and if the container is resized, all three columns shrink or grow together while staying equal in width.
Common Mistakes
- Forgetting that justify-content aligns along the main axis while align-items aligns along the cross axis, and mixing them up when flex-direction is column.
- Not setting flex-wrap: wrap on a row of items and being surprised when they overflow the container instead of moving to a new line.
- Using width on flex items when flex-basis (or the flex shorthand) would interact more predictably with grow/shrink behavior.
- Applying flex properties to a container without first setting display: flex on it, so the properties have no effect at all.
Exercise
Turn main into a flex container so that the heading, the paragraph and the button sit in one row, centred vertically, with 16px between them, and with the button pushed to the far right.
Expected result: heading and paragraph on the left, the button at the right edge, all aligned on their vertical centres.
/* The page contains: <main> with an <h1>, a <p> and a <button> */
main {
/* TODO: a flex row, centred vertically, with a 16px gap */
}
button {
/* TODO: push the button to the far right */
}
Show hints
align-items: centercentres the items on the cross axis, which is vertical in a row.- An automatic margin absorbs the free space:
margin-left: autopushes an item to the right.
Show solution
/* The page contains: <main> with an <h1>, a <p> and a <button> */
main {
display: flex;
align-items: center;
gap: 16px;
}
button {
margin-left: auto;
}
Quick quiz
1. In a flex container with the default direction, which property aligns the items horizontally?
- A. align-items
- B. align-content
- C. justify-content
- D. flex-direction
Show answer
C. justify-content works along the main axis, which is horizontal for a row. align-items works on the cross axis.
2. What does flex: 1 on every item of a row do?
- A. The items wrap onto new lines
- B. Each item is 1px wide
- C. Only the first item grows
- D. The items share the available space equally
Show answer
D. It is shorthand for flex-grow 1, flex-shrink 1 and flex-basis 0.
3. By default, what happens when the items of a flex row do not fit?
- A. They shrink to fit on one line, because flex-wrap defaults to nowrap
- B. They are hidden
- C. The container scrolls
- D. They wrap onto a new line
Show answer
A. Set flex-wrap: wrap to allow the items to move onto new lines.
Interview questions
What are the main axis and the cross axis?
Show answer
The main axis is the direction in which the flex items are laid out, set by flex-direction: horizontal for row, vertical for column. The cross axis is perpendicular to it. justify-content distributes items along the main axis, and align-items aligns them along the cross axis. When the direction changes to column, the two properties swap the directions they affect.
How do you centre an element both horizontally and vertically?
Show answer
Make its parent a flex container and centre on both axes: display: flex; justify-content: center; align-items: center;, giving the parent a height to centre within. With grid it is shorter still: display: grid; place-items: center;. Both work whatever the size of the child.
Key Points to Remember
- display: flex on a parent turns its direct children into flex items along a single main axis.
- justify-content controls main-axis alignment; align-items controls cross-axis alignment.
- flex-grow, flex-shrink, and flex-basis (often combined via the flex shorthand) control how individual items size themselves.
- Flexbox is one-dimensional — for full two-dimensional layouts (rows and columns together), CSS Grid is usually the better tool.
Practice in the playground
Write and run your own code for this topic, or start from the exercise or an example. Shows a live preview of your HTML, CSS and JavaScript. Your code for each topic is kept in this browser.
Run the examples
Change an input, predict the result, then compare it with the output. Explain why the result changes.
Written by
WebNest Studio Engineering Team
Practical lessons from developers working with Java, Python, React, databases and production systems.
Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering