CodeMIRAI
0 XP

Aligning with Flexbox

3 min read 5 runnable examples Quiz included

A flex container has two axes. The main axis runs in the flex-direction, left to right for a row. The cross axis runs across it.

  • justify-content aligns items along the main axis.
  • align-items aligns them along the cross axis.

Try them

HTML
<style>
  body { font-family: system-ui; }
  .controls { display: flex; flex-wrap: wrap; gap: 14px; margin-bottom: 10px; font-size: 14px; }
  .box { display: flex; height: 160px; gap: 8px; padding: 8px; border: 2px dashed #b7adff; border-radius: 10px; background: #f4f2ff; }
  .box div { padding: 8px 12px; border-radius: 6px; background: #5a48f5; color: white; }
  .box div:nth-child(2) { padding: 22px 12px; }
  code { display: inline-block; margin-top: 8px; padding: 6px 10px; border-radius: 6px; background: #11151f; color: #e9ecf5; font-size: 13px; }
</style>
<div class="controls">
  <label>justify-content
    <select id="jc">
      <option>flex-start</option><option>center</option><option>flex-end</option>
      <option>space-between</option><option>space-around</option><option>space-evenly</option>
    </select>
  </label>
  <label>align-items
    <select id="ai">
      <option>stretch</option><option>flex-start</option><option>center</option>
      <option>flex-end</option><option>baseline</option>
    </select>
  </label>
  <label>flex-direction
    <select id="fd"><option>row</option><option>column</option></select>
  </label>
</div>
<div class="box" id="box"><div>One</div><div>Two</div><div>Three</div></div>
<code id="css"></code>
<script>
  const box = document.querySelector("#box");
  const pick = (id) => document.querySelector(id).value;
  function update() {
    box.style.justifyContent = pick("#jc");
    box.style.alignItems = pick("#ai");
    box.style.flexDirection = pick("#fd");
    document.querySelector("#css").textContent =
      `flex-direction: ${pick("#fd")}; justify-content: ${pick("#jc")}; align-items: ${pick("#ai")};`;
  }
  document.querySelectorAll("select").forEach((s) => s.addEventListener("change", update));
  update();
</script>

Switch flex-direction to column, and the two properties swap roles: justify-content now works vertically and align-items horizontally.

The values

justify-contentEffect
flex-startpacked at the start (the default)
centerpacked in the middle
flex-endpacked at the end
space-betweenfirst and last items at the edges, equal gaps between
space-aroundequal space around each item, so the edge gaps are half-size
space-evenlyexactly equal gaps everywhere, edges included
align-itemsEffect
stretchitems stretch to fill the cross axis (the default)
flex-start, flex-endto the top or bottom, in a row
centercentred across
baselinethe first lines of text line up

Centring anything

HTML
<style>
  .stage { display: flex; justify-content: center; align-items: center; height: 180px; border-radius: 12px; background: #11151f; }
  .dialog { padding: 18px 22px; border-radius: 10px; background: white; font: 15px system-ui; }
</style>
<div class="stage"><div class="dialog">Perfectly centred</div></div>

Two lines centre anything in both directions, a job that once took clever tricks. Grid does it in one: display: grid; place-items: center.

One item differently: align-self

HTML
<style>
  .row { display: flex; align-items: flex-start; gap: 8px; height: 130px; padding: 8px; border-radius: 10px; background: #f4f2ff; font: 14px system-ui; }
  .row div { padding: 10px; border-radius: 6px; background: #0aa9cf; color: white; }
  .row .down { align-self: flex-end; background: #e0663a; }
</style>
<div class="row"><div>start</div><div class="down">align-self: flex-end</div><div>start</div></div>

align-self overrides align-items for a single item.

Auto margins push items apart

HTML
<style>
  .bar { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-radius: 10px; background: #11151f; font: 14px system-ui; }
  .bar span { color: #e9ecf5; }
  .bar .push { margin-left: auto; }
  .bar button { padding: 8px 14px; border: 0; border-radius: 6px; background: #5a48f5; color: white; }
</style>
<div class="bar">
  <span>☰</span><span>Dashboard</span>
  <span class="push">Asha</span><button>Sign out</button>
</div>

An auto margin soaks up all the free space on its side, so margin-left: auto shoves its item, and everything after it, to the far end.

Changing the visual order

HTML
<style>
  .row { display: flex; gap: 8px; font: 14px system-ui; }
  .row div { padding: 10px 14px; border-radius: 6px; background: #eef0ff; }
  .row .first { order: -1; background: #d9f7ea; }
</style>
<div class="row"><div>1</div><div>2</div><div class="first">3, with order: -1</div></div>

order changes where an item is drawn (the default is 0, and lower numbers come first), but not its place in the HTML. Screen readers and the Tab key still follow the HTML, so don't use order where the sequence carries meaning.

Wrapped lines: align-content

When items wrap onto several lines, align-content spaces out the lines along the cross axis. It takes the same values as justify-content, and does nothing when there's only one line.

Finished this lesson?Mark it complete to earn +20 XP and move your progress on.