Home >CSS >Modern CSS >Flexbox: items side by side and alignment

Flexbox: items side by side and alignment

A menu, a row of buttons, a header with the logo on the left and links on the right – placing items side by side is done with flexbox in CSS today. No floats, no gaps between inline-block elements and with vertical alignment that used to require tricks.

The basics: display: flex

<nav class="menu">
  <a href="/">Home</a>
  <a href="/articles/">Articles</a>
  <a href="/contact/">Contact</a>
</nav>
.menu {
  display: flex;
  gap: 12px;
}
result
Home
Articles
Contact

An element with display: flex is a flex container and its direct children are items. The items line up in a row side by side and by default they do not wrap onto another line. The gap property sets the space between the items – only between them, not before the first one or after the last one.

Spaces and line breaks between the tags in the HTML are not displayed in a flex container, so the familiar gap between inline-block elements disappears as well. float and vertical-align have no effect on the items either.

Alignment in the row: justify-content

.menu {
  display: flex;
  justify-content: space-between;
}
result
Home
Articles
Contact

Flexbox has two axes. The main axis runs in the direction in which the items are placed – horizontally for a row. How the items are distributed along it is set by justify-content:

  • flex-start – at the start (this is also how the items behave without the setting),
  • center – in the middle,
  • flex-end – at the end,
  • space-between – the first item at the start, the last one at the end and the free space spread evenly between them,
  • space-around – the same space around each item, so the gap between items is twice as big as at the edges,
  • space-evenly – equal gaps between the items and at the edges.

Vertical alignment: align-items

The cross axis is perpendicular to the main one – vertical for a row. Without a setting, the items stretch to the height of the row (stretch), so they are equally tall even if their content differs in length. Other values of align-items are flex-start, center, flex-end and baseline (alignment by the baseline of the first line of text). A typical use is the header of a website:

<header class="header">
  <a class="logo" href="/">Bistro</a>
  <nav class="links">
    <a href="/menu/">Menu</a>
    <a href="/contact/">Contact</a>
  </nav>
</header>
.header {
  display: flex;
  align-items: center;
  gap: 20px;
}
.logo {
  font-size: 28px;
  margin-right: auto;
}
.links {
  display: flex;
  gap: 12px;
}
result
Bistro
Menu
Contact
  • align-items: center aligns the links vertically to the middle of the taller logo.
  • margin-right: auto on the logo takes up all the free space in the row and pushes the other items to the right edge. The opposite works with margin-left: auto on the item from which the rest of the row should be pushed to the right.
  • An item can itself be a flex container – here the navigation with the links.

Centering horizontally and vertically

<div class="box">
  <div class="message">Saved</div>
</div>
.box {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 200px;
}
result
Saved

The content is in the middle regardless of its height and width – without line-height, without absolute positioning and without knowing the dimensions. Grid offers an even shorter notation: display: grid; place-items: center;.

One below the other: flex-direction

<form class="form">
  <label for="name">Name</label>
  <input id="name" type="text">
  <button type="submit">Send</button>
</form>
.form {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
result

flex-direction: column stacks the items one below the other. The main axis is then vertical, so justify-content aligns vertically and align-items horizontally. The default stretching (stretch) now works in width – the field and the button are as wide as the whole form.

The values row-reverse and column-reverse reverse the order of the items. Only the display is reversed, though – screen readers and moving with the Tab key still follow the order in the HTML. If the order should be different for everyone, change it in the HTML.

Browser support

Flexbox works in all current browsers. The gap property came to flexbox later than to grid – Safari supports it in flexbox since version 14.1 from 2021.

Related articles:
Flexbox: item size and wrapping
CSS grid: page layout
Responsive grid without media queries