CSS Flexbox Layout

CSS Flexbox Layout

CSS Flexbox is a powerful layout system that makes it easy to design flexible and responsive layouts. This tutorial covers everything you need to know about Flexbox.

What is Flexbox?

Flexbox (Flexible Box Layout) is a one-dimensional layout method that allows you to arrange items in rows or columns. It’s perfect for creating responsive layouts without using floats or positioning.

Basic Concepts

Container and Items

In Flexbox, you have a flex container (parent) and flex items (children).

.container {
  display: flex; /* This makes it a flex container */
}

.item {
  /* These are flex items */
}
<div class="container">
  <div class="item">Item 1</div>
  <div class="item">Item 2</div>
  <div class="item">Item 3</div>
</div>

Flex Container Properties

1. flex-direction

Controls the direction of flex items.

.container {
  display: flex;
  flex-direction: row; /* Default: left to right */
}

.container {
  flex-direction: row-reverse; /* Right to left */
}

.container {
  flex-direction: column; /* Top to bottom */
}

.container {
  flex-direction: column-reverse; /* Bottom to top */
}

2. flex-wrap

Controls whether flex items wrap or not.

.container {
  flex-wrap: nowrap; /* Default: all items on one line */
}

.container {
  flex-wrap: wrap; /* Items wrap to next line if needed */
}

.container {
  flex-wrap: wrap-reverse; /* Items wrap in reverse direction */
}

3. flex-flow

Shorthand for flex-direction and flex-wrap.

.container {
  flex-flow: row wrap; /* Same as: flex-direction: row; flex-wrap: wrap; */
}

4. justify-content

Aligns flex items along the main axis (horizontally by default).

.container {
  justify-content: flex-start; /* Items at the start */
}

.container {
  justify-content: flex-end; /* Items at the end */
}

.container {
  justify-content: center; /* Items centered */
}

.container {
  justify-content: space-between; /* Equal space between items */
}

.container {
  justify-content: space-around; /* Equal space around items */
}

.container {
  justify-content: space-evenly; /* Equal space between and around items */
}

5. align-items

Aligns flex items along the cross axis (vertically by default).

.container {
  align-items: stretch; /* Default: items stretch to fill container */
}

.container {
  align-items: flex-start; /* Items at the start of cross axis */
}

.container {
  align-items: flex-end; /* Items at the end of cross axis */
}

.container {
  align-items: center; /* Items centered on cross axis */
}

.container {
  align-items: baseline; /* Items aligned by text baseline */
}

6. align-content

Aligns flex lines when there’s extra space in the cross axis (only works with multiple lines).

.container {
  align-content: flex-start; /* Lines packed to start */
}

.container {
  align-content: flex-end; /* Lines packed to end */
}

.container {
  align-content: center; /* Lines centered */
}

.container {
  align-content: space-between; /* Equal space between lines */
}

.container {
  align-content: space-around; /* Equal space around lines */
}

.container {
  align-content: stretch; /* Lines stretch to fill space */
}

Flex Item Properties

1. flex-grow

Controls how much a flex item grows relative to other items.

.item1 {
  flex-grow: 0; /* Default: doesn't grow */
}

.item2 {
  flex-grow: 1; /* Grows to fill available space */
}

.item3 {
  flex-grow: 2; /* Grows twice as much as item2 */
}

2. flex-shrink

Controls how much a flex item shrinks relative to other items.

.item {
  flex-shrink: 1; /* Default: can shrink */
}

.item {
  flex-shrink: 0; /* Cannot shrink */
}

3. flex-basis

Defines the default size of a flex item before space is distributed.

.item {
  flex-basis: auto; /* Default: based on content size */
}

.item {
  flex-basis: 200px; /* Fixed width of 200px */
}

.item {
  flex-basis: 20%; /* 20% of container width */
}

4. flex

Shorthand for flex-grow, flex-shrink, and flex-basis.

.item {
  flex: 0 1 auto; /* Default: don't grow, can shrink, size based on content */
}

.item {
  flex: 1; /* Same as: 1 1 0% - grows and shrinks, starts at 0 */
}

.item {
  flex: 2 1 200px; /* Grows twice as much, can shrink, starts at 200px */
}

5. align-self

Allows individual flex items to override the align-items setting.

.item {
  align-self: auto; /* Default: uses container's align-items */
}

.item {
  align-self: flex-start;
}

.item {
  align-self: flex-end;
}

.item {
  align-self: center;
}

.item {
  align-self: baseline;
}

.item {
  align-self: stretch;
}

Practical Examples

1. Centering Content

Perfect for centering items both horizontally and vertically.

.center-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

2. Navigation Bar

Create a responsive navigation bar.

.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem;
  background-color: #333;
  color: white;
}

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

.nav-links {
  display: flex;
  gap: 1rem;
}

.nav-links a {
  color: white;
  text-decoration: none;
}
<nav class="navbar">
  <div class="nav-brand">MySite</div>
  <div class="nav-links">
    <a href="#">Home</a>
    <a href="#">About</a>
    <a href="#">Contact</a>
  </div>
</nav>

3. Card Layout

Create a responsive grid of cards.

.card-container {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  padding: 1rem;
}

.card {
  flex: 1 1 300px; /* Grows and shrinks, minimum 300px */
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  padding: 1rem;
}

.card-header {
  font-size: 1.25rem;
  font-weight: bold;
  margin-bottom: 0.5rem;
}

.card-content {
  color: #666;
  line-height: 1.5;
}
<div class="card-container">
  <div class="card">
    <div class="card-header">Card 1</div>
    <div class="card-content">This is the content for card 1.</div>
  </div>
  <div class="card">
    <div class="card-header">Card 2</div>
    <div class="card-content">This is the content for card 2.</div>
  </div>
  <div class="card">
    <div class="card-header">Card 3</div>
    <div class="card-content">This is the content for card 3.</div>
  </div>
</div>

4. Holy Grail Layout

Classic web layout with header, footer, and three columns.

.holy-grail {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.header, .footer {
  background: #333;
  color: white;
  padding: 1rem;
  text-align: center;
}

.content {
  display: flex;
  flex: 1;
}

.main {
  flex: 1;
  padding: 1rem;
}

.sidebar-left, .sidebar-right {
  width: 200px;
  background: #f5f5f5;
  padding: 1rem;
}

.sidebar-left {
  order: -1; /* Moves to the left */
}
<div class="holy-grail">
  <header class="header">Header</header>
  <div class="content">
    <aside class="sidebar-left">Left Sidebar</aside>
    <main class="main">Main Content</main>
    <aside class="sidebar-right">Right Sidebar</aside>
  </div>
  <footer class="footer">Footer</footer>
</div>

5. Form Layout

Create responsive form layouts.

.form-group {
  display: flex;
  flex-direction: column;
  margin-bottom: 1rem;
}

.form-row {
  display: flex;
  gap: 1rem;
}

.form-row .form-group {
  flex: 1;
}

.form-label {
  margin-bottom: 0.25rem;
  font-weight: bold;
}

.form-input {
  padding: 0.5rem;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.form-button {
  padding: 0.5rem 1rem;
  background: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
<form class="form">
  <div class="form-row">
    <div class="form-group">
      <label class="form-label">First Name</label>
      <input type="text" class="form-input" />
    </div>
    <div class="form-group">
      <label class="form-label">Last Name</label>
      <input type="text" class="form-input" />
    </div>
  </div>
  <div class="form-group">
    <label class="form-label">Email</label>
    <input type="email" class="form-input" />
  </div>
  <button type="submit" class="form-button">Submit</button>
</form>

Common Flexbox Patterns

1. Equal Height Columns

.container {
  display: flex;
}

.column {
  flex: 1;
  /* All columns automatically have equal height */
}

2. Sticky Footer

.page {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.content {
  flex: 1;
}

3. Mobile-First Responsive Design

.container {
  display: flex;
  flex-direction: column;
}

@media (min-width: 768px) {
  .container {
    flex-direction: row;
  }
}

Browser Support

Flexbox is supported in all modern browsers:

  • Chrome 29+
  • Firefox 28+
  • Safari 9+
  • Edge 12+
  • Internet Explorer 11 (with some bugs)

For older browsers, you may need vendor prefixes:

.container {
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
}

Best Practices

  1. Use semantic HTML: Keep your HTML meaningful
  2. Mobile-first approach: Start with column layout, then change to row on larger screens
  3. Avoid fixed widths: Use flexible units like percentages or flex
  4. Test thoroughly: Check how your layout behaves with different content sizes
  5. Use gap for spacing: Modern browsers support the gap property for flex containers
/* Modern approach with gap */
.container {
  display: flex;
  gap: 1rem; /* Adds space between all flex items */
}

/* Fallback for older browsers */
.container {
  display: flex;
}
.container > * + * {
  margin-left: 1rem;
}

External Resources:

Related Tutorials:

Last updated on