Skip to main content

CSS Flexbox

Updated Mar 20, 2019 ·

Early Web Layouts

Web pages were originally structured using basic HTML tables.

  • Used <table>, <tr>, and <td> elements
  • Allowed multi-column layouts by adjusting column widths
  • Still useful for tabular data but not for layouts

Tables are not ideal for layouts because they mix structure with design, making updates difficult.

Transition to Display

To improve layouts, developers started using display properties.

  • display: inline-block for placing elements side by side
  • position: absolute for precise positioning
  • float: left/right for arranging elements in columns

While these methods improved layouts, they introduced complexities in alignment and responsiveness.

The Problem with Floats

Floats were widely used but had drawbacks.

  • Difficult to align elements properly
  • Required clearfix hacks for layout stability
  • Not designed for complex grid structures

Floats work well for wrapping text around images but are not ideal for building full-page layouts.

Using Flexbox

Flexbox simplifies layout creation with a flexible approach.

  • display: flex creates a flex container
  • Items adjust dynamically based on available space
  • Aligns items easily with justify-content and align-items

Example: Creating a Flexbox Layout

Sample files: Github

<div class="container">
<div class="box">Box 1</div>
<div class="box">Box 2</div>
<div class="box">Box 3</div>
</div>
.container {
display: flex;
gap: 10px;
}
.box {
background: #66D2CE;
padding: 20px;
flex: 1;
}

Each .box will be evenly spaced inside .container, adjusting dynamically based on the available width.

Main and Cross Axis

Flexbox layouts are structured around two axes:

  • Main axis

    • Defined by flex-direction
    • row: main axis is horizontal
    • column: main axis is vertical
  • Cross axis

    • Perpendicular to the main axis
    • Helps control item alignment in the perpendicular direction

Flex Direction

The flex-direction property determines how flex items are arranged inside a container.

  • Default value: row (items align from left to right)
  • column: items align from top to bottom
  • row-reverse: items align from right to left
  • column-reverse: items align from bottom to top

Example: Modify the default layout using flex-direction:

.container {
display: flex;
flex-direction: column;
}
  • Items now align top to bottom
  • The main axis becomes vertical
  • The cross axis moves left to right

Sample file can be found here: Github

Flex Basis

The flex-basis property controls the initial size of flex items along the main axis.

  • In row direction: flex-basis sets width
  • In column direction: flex-basis sets height
  • Applies to child elements, not the container

Example:

.container > * {
flex-basis: 100px;
}

.container {
display: flex;
flex-direction: row;
}
  • When row, items have a width of 100px
  • When column, items have a height of 100px
  • Helps control item sizes within a flex container

Using the previous example, we've set the flex-direction to column so each of the boxes will have a height of 100px.

If it was set to flex-direction: row, the flex-basis sets the width to 100px and the arrangement would look like this:

Control Order with order

The order property changes the arrangement of child items inside a flex container.

  • Default order is 0, following HTML structure
  • Higher values move items further right
  • Lower values move items further left

Example: Without ordering, the box items are arranged the same way they are defined in the

Sample files found in Github

If we set the order of the box 1 (red) to 1, we're moving it further down below the other elements which have a default order of 0.

.red {
background: #D76C82;
order: 1
}

.green {
background: #66D2CE;
}

.blue {
background: #578FCA;
}

Wrap Items with flex-wrap

By default, items stay in a single row and do not wrap.

  • nowrap (default) keeps items in one row
  • wrap moves items to the next line when space runs out
  • wrap-reverse wraps items from bottom to top
.container {
display: flex;
flex-wrap: wrap;
}

Sample files: Github

Using flex-wrap ensures items don’t overflow and stay visible within the container.

Setting it to wrap-reverse:

Align Items with justify-content

This property controls spacing along the main axis (horizontal by default).

  • flex-start (default) aligns items to the left
  • flex-end moves items to the right
  • center centers items
  • space-between distributes items with space in between
  • space-around adds equal space on both sides of each item
  • space-evenly ensures equal spacing everywhere
.container {
display: flex;
justify-content: space-between;
}

To view the sample files, check out Github.

You may also view the live demo here: CSS Justify Content

Align Items with align-items

This property aligns items along the cross-axis (vertical by default).

  • flex-start aligns items at the top
  • flex-end moves items to the bottom
  • center aligns items in the middle
  • stretch makes items expand to fill the container height
  • baseline aligns items by their text baselines
.container {
display: flex;
flex-wrap: nowrap;
align-items: center;
}

Using align-items helps in vertically positioning elements inside the container.

To view the sample files, check out Github.

Adjust Individual Items with align-self

This property overrides align-items for a specific child.

  • Works like align-items but for a single item
  • Lets specific items behave differently from others
.item {
align-self: flex-end;
}

For our example, we want to set all boxes to be aligned to the top, except for:

  • orange - position at the center
  • green - position at the bottom

To view the sample files, check out Github.

Align Content in Flexbox

Align-content controls how wrapped flex items are aligned along the cross axis.

  • Works only with flex-wrap: wrap
  • Affects how rows of flex items are spaced
  • Different from align-items

When items wrap into multiple rows, align-content decides how those rows are spaced. Without wrapping, this property has no effect.

Align-Items and Align-Content

align-items and align-content seem similar but behave differently.

  • align-items: Aligns individual items in a single row
  • align-content: Aligns multiple rows of items
  • align-content does nothing if all items fit in one row

When there is only one row, align-items is enough. But if flex items wrap, align-content helps control row spacing.

Common Values

Different values change how wrapped rows are positioned.

  • flex-start – Rows packed at the start
  • flex-end – Rows packed at the end
  • center – Rows centered
  • space-between – Evenly distributed with no space at edges
  • space-around – Evenly distributed with space around them
  • stretch – Rows stretch to fill container height

Example:

.container {
display: flex;
flex-wrap: wrap;
align-content: center;
height: 300px;
border: 1px solid black;
}

.item {
width: 100px;
height: 100px;
background: lightblue;
margin: 5px;
}

Expected Result:

  • If flex items wrap, they will be centered vertically inside .container.
  • Without flex-wrap: wrap, align-content does nothing.