Introduction to Flexbox

CSS Flexbox (Flexible Box Layout) is a one-dimensional layout method designed for arranging items in rows or columns. It provides a more efficient way to distribute space and align items, even when their size is unknown or dynamic.
Flexbox is particularly useful for components of an application and small-scale layouts, while CSS Grid is better suited for larger-scale layouts.

Basic Concepts

Flexbox involves two main components: the flex container (parent) and flex items (children).
Flexbox Container and Items

Flexbox Container and Items

Creating a Flex Container

To create a flex container, set the display property to flex or inline-flex:
.container {
  display: flex; /* Creates a block-level flex container */
}

.container-inline {
  display: inline-flex; /* Creates an inline-level flex container */
}

Flex Container Properties

Flex Direction

The flex-direction property establishes the main axis, defining the direction flex items are placed in the flex container.
.container {
  display: flex;
  
  /* Default: left to right in ltr languages */
  flex-direction: row;
  
  /* Right to left */
  flex-direction: row-reverse;
  
  /* Top to bottom */
  flex-direction: column;
  
  /* Bottom to top */
  flex-direction: column-reverse;
}
Flex Direction Options

Flex Direction Options

Flex Wrap

The flex-wrap property controls whether flex items are forced onto a single line or can wrap onto multiple lines.
.container {
  display: flex;
  
  /* Default: all items on one line */
  flex-wrap: nowrap;
  
  /* Items wrap onto multiple lines */
  flex-wrap: wrap;
  
  /* Items wrap onto multiple lines in reverse */
  flex-wrap: wrap-reverse;
}
Flex Wrap Options

Flex Wrap Options

Flex Flow

The flex-flow property is a shorthand for flex-direction and flex-wrap.
.container {
  display: flex;
  
  /* <flex-direction> <flex-wrap> */
  flex-flow: row nowrap; /* Default */
  flex-flow: column wrap;
  flex-flow: row-reverse wrap-reverse;
}

Justify Content

The justify-content property aligns flex items along the main axis, distributing extra free space.
.container {
  display: flex;
  
  /* Default: items are packed toward the start line */
  justify-content: flex-start;
  
  /* Items are packed toward the end line */
  justify-content: flex-end;
  
  /* Items are centered along the line */
  justify-content: center;
  
  /* Items are evenly distributed with equal space between them */
  justify-content: space-between;
  
  /* Items are evenly distributed with equal space around them */
  justify-content: space-around;
  
  /* Items are evenly distributed with equal space around them and at the ends */
  justify-content: space-evenly;
}
Justify Content Options

Justify Content Options

Align Items

The align-items property aligns flex items along the cross axis (perpendicular to the main axis).
.container {
  display: flex;
  
  /* Default: items are stretched to fill the container */
  align-items: stretch;
  
  /* Items are placed at the start of the cross axis */
  align-items: flex-start;
  
  /* Items are placed at the end of the cross axis */
  align-items: flex-end;
  
  /* Items are centered along the cross axis */
  align-items: center;
  
  /* Items are aligned such that their baselines align */
  align-items: baseline;
}
Align Items Options

Align Items Options

Align Content

The align-content property aligns a flex container’s lines within the flex container when there is extra space in the cross axis. It only applies when there are multiple lines (when flex-wrap: wrap or flex-wrap: wrap-reverse).
.container {
  display: flex;
  flex-wrap: wrap;
  height: 500px; /* Container needs height for this to have an effect */
  
  /* Default: lines are packed toward the start of the container */
  align-content: flex-start;
  
  /* Lines are packed toward the end of the container */
  align-content: flex-end;
  
  /* Lines are centered in the container */
  align-content: center;
  
  /* Lines are evenly distributed with equal space between them */
  align-content: space-between;
  
  /* Lines are evenly distributed with equal space around them */
  align-content: space-around;
  
  /* Lines stretch to fill the remaining space */
  align-content: stretch;
}
Align Content Options

Align Content Options

Flex Item Properties

Order

The order property controls the order in which flex items appear in the flex container. By default, items are laid out in the source order, but order can change this.
.item {
  order: 0; /* Default */
}

.first {
  order: -1; /* Appears before items with higher order values */
}

.last {
  order: 1; /* Appears after items with lower order values */
}
Order Property Example

Order Property Example

Flex Grow

The flex-grow property defines the ability for a flex item to grow if necessary. It accepts a unitless value that serves as a proportion, determining how much of the available space the item should take up.
.item {
  flex-grow: 0; /* Default: does not grow */
}

.item-grow {
  flex-grow: 1; /* Can grow to fill available space */
}

.item-grow-double {
  flex-grow: 2; /* Grows twice as much as items with flex-grow: 1 */
}
Flex Grow Example

Flex Grow Example

Flex Shrink

The flex-shrink property defines the ability for a flex item to shrink if necessary. Like flex-grow, it accepts a unitless value.
.item {
  flex-shrink: 1; /* Default: can shrink if needed */
}

.item-no-shrink {
  flex-shrink: 0; /* Does not shrink */
}

.item-shrink-double {
  flex-shrink: 2; /* Shrinks twice as much as items with flex-shrink: 1 */
}

Flex Basis

The flex-basis property defines the default size of an element before the remaining space is distributed. It can be a length (e.g., 20%, 5rem, etc.) or a keyword (auto, content).
.item {
  flex-basis: auto; /* Default: size based on content */
}

.item-basis {
  flex-basis: 200px; /* Initial main size of 200px */
}

.item-percent {
  flex-basis: 50%; /* Initial main size of 50% of the container */
}

Flex Shorthand

The flex property is a shorthand for flex-grow, flex-shrink, and flex-basis.
.item {
  /* <flex-grow> <flex-shrink> <flex-basis> */
  flex: 0 1 auto; /* Default */
  
  /* One value, unitless: flex-grow */
  flex: 1; /* Same as flex: 1 1 0% */
  
  /* One value, width/height: flex-basis */
  flex: 10em; /* Same as flex: 1 1 10em */
  
  /* Two values: flex-grow | flex-basis */
  flex: 1 30px; /* Same as flex: 1 1 30px */
  
  /* Two values: flex-grow | flex-shrink */
  flex: 2 2; /* Same as flex: 2 2 0% */
  
  /* Three values: flex-grow | flex-shrink | flex-basis */
  flex: 2 1 200px;
  
  /* Global values */
  flex: initial; /* Same as flex: 0 1 auto */
  flex: auto; /* Same as flex: 1 1 auto */
  flex: none; /* Same as flex: 0 0 auto */
}
The flex shorthand is recommended over the individual properties. The shorthand sets the other values intelligently.

Align Self

The align-self property allows the default alignment (set by align-items) to be overridden for individual flex items.
.item {
  /* Default: inherits the align-items value from the parent */
  align-self: auto;
  
  /* Start of the cross axis */
  align-self: flex-start;
  
  /* End of the cross axis */
  align-self: flex-end;
  
  /* Center of the cross axis */
  align-self: center;
  
  /* Baseline alignment */
  align-self: baseline;
  
  /* Stretch to fill the container */
  align-self: stretch;
}
Align Self Example

Align Self Example

Common Flexbox Patterns

Centering an Element

One of the most common uses of Flexbox is to center an element both horizontally and vertically:
.container {
  display: flex;
  justify-content: center; /* Center horizontally */
  align-items: center; /* Center vertically */
  height: 300px; /* Container needs height for vertical centering */
}
Flexbox is perfect for creating navigation bars:
.navbar {
  display: flex;
  justify-content: space-between; /* Space between logo and nav items */
  align-items: center;
  padding: 1rem;
  background-color: #333;
  color: white;
}

.logo {
  font-size: 1.5rem;
  font-weight: bold;
}

.nav-links {
  display: flex;
  gap: 1rem; /* Space between nav links */
}

.nav-links a {
  color: white;
  text-decoration: none;
}

Card Layout

Flexbox can create responsive card layouts:
.card-container {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.card {
  flex: 1 1 300px; /* Grow, shrink, basis */
  padding: 20px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

Holy Grail Layout

The classic “holy grail” layout (header, footer, and three columns) can be implemented with Flexbox:
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh; /* Full viewport height */
  margin: 0;
}

header, footer {
  background-color: #f0f0f0;
  padding: 1rem;
}

.content {
  display: flex;
  flex: 1; /* Takes up all available space */
}

.sidebar-left, .sidebar-right {
  background-color: #e0e0e0;
  padding: 1rem;
  flex: 0 0 200px; /* Don't grow, don't shrink, fixed width */
}

main {
  flex: 1; /* Takes up all available space */
  padding: 1rem;
  background-color: white;
}

/* Responsive adjustment */
@media (max-width: 768px) {
  .content {
    flex-direction: column;
  }
  
  .sidebar-left, .sidebar-right {
    flex: 0 0 auto; /* Auto height */
  }
}

Equal Height Columns

Flexbox naturally creates equal height columns:
.container {
  display: flex;
}

.column {
  flex: 1; /* Each column takes up equal space */
  padding: 20px;
}

.column:nth-child(odd) {
  background-color: #f0f0f0;
}

.column:nth-child(even) {
  background-color: #e0e0e0;
}

Responsive Flexbox

Flexbox is inherently responsive, but you can enhance its behavior with media queries:
.container {
  display: flex;
  flex-wrap: wrap;
}

.item {
  flex: 1 1 300px; /* Grow, shrink, basis */
  margin: 10px;
  padding: 20px;
  background-color: #f0f0f0;
}

@media (max-width: 600px) {
  .container {
    flex-direction: column;
  }
  
  .item {
    flex-basis: auto; /* Let items size naturally */
  }
}

Browser Support and Fallbacks

Flexbox is supported in all modern browsers, but if you need to support older browsers, consider using feature detection or providing fallbacks:
/* Fallback for older browsers */
.container {
  display: block;
  text-align: center;
}

.item {
  display: inline-block;
  width: 30%;
  margin: 1%;
  vertical-align: top;
}

/* Modern browsers with Flexbox support */
@supports (display: flex) {
  .container {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-around;
    text-align: left;
  }
  
  .item {
    display: block;
    flex: 1 1 300px;
    margin: 10px;
    width: auto;
  }
}

Flexbox vs. Grid

While Flexbox and Grid can sometimes be used to achieve similar layouts, they have different strengths:
  • Flexbox is one-dimensional, focusing on either rows OR columns
  • Grid is two-dimensional, handling both rows AND columns simultaneously
Use Flexbox for:
  • One-dimensional layouts (rows OR columns)
  • When you want content to determine the layout
  • Components, navigation, small-scale layouts
Use Grid for:
  • Two-dimensional layouts (rows AND columns)
  • When you want the layout to determine the content
  • Overall page layout, complex grid-based interfaces

Conclusion

CSS Flexbox provides a powerful and intuitive way to create flexible layouts that work across different screen sizes. By understanding the properties of both flex containers and flex items, you can create complex layouts with relatively simple code. Key takeaways:
  1. Flexbox is a one-dimensional layout method for arranging items in rows or columns
  2. The parent element becomes a flex container with display: flex
  3. Flex container properties control the overall layout direction and alignment
  4. Flex item properties control how individual items grow, shrink, and align
  5. Flexbox is perfect for responsive designs and can adapt to different screen sizes
With these concepts in mind, you can leverage Flexbox to create efficient, flexible, and responsive layouts for your web projects.