Quick answer: Flexbox in Tailwind is a handful of utilities that control one row or column of items: flex to switch a container on, flex-col or flex-row for direction, justify-* for spacing along the main axis, items-* for alignment across it, and gap-* for the space between. grow, shrink-0 and basis-* decide how much room each child takes. This guide explains the split between the two axes and builds a real card footer and a navbar that holds up on a phone.

Two axes, two families of utilities

The single idea that makes flexbox click is that there are always two axes. The main axis is the direction items flow in, and the cross axis is the other one. Every utility name tells you which axis it belongs to, and once you notice that pattern you stop guessing.

AxisUtilitiesControls
Mainjustify-start, justify-between, justify-centerHow items spread along the flow direction
Crossitems-start, items-center, items-stretchHow items line up across it
Bothgap-4, grow, shrink-0, basis-*Spacing and how room is shared

In a row, justify-* spreads items left to right and items-* moves them up and down. Flip the container with flex-col and the axes swap roles, which surprises people once and then never again. That is the whole mental model.

The three utilities you will type most

Almost every flex layout is flex plus one justify, one items and a gap. Learn these three and you can build the majority of real interfaces.

<div class="flex items-center justify-between gap-4">
  <h2 class="text-lg font-semibold text-slate-900">Pro plan</h2>
  <span class="rounded-full bg-teal-50 px-3 py-1 text-sm text-teal-700">Popular</span>
</div>

items-center stops the badge floating at the top because its text is smaller than the heading. justify-between pins the heading left and the badge right without a single line of positioning CSS. gap-4 is the minimum space between them at narrow widths.

Sharing space: grow, shrink and basis

When children share a row, three properties matter, and Tailwind gives each a utility. basis-* sets the starting size, grow lets an item take leftover room, and shrink-0 refuses to let one collapse. A search bar that fills whatever is left over is the classic case.

<div class="flex items-center gap-3">
  <input type="search" placeholder="Search..."
         class="min-w-0 flex-1 rounded-md border border-slate-300 px-3 py-2" />
  <button class="shrink-0 rounded-md bg-teal-600 px-4 py-2 font-medium text-white">Go</button>
</div>

The two details that bite people are min-w-0 and shrink-0. A flex child defaults to a minimum width of its content, so a long input will refuse to shrink and will push the button off the edge; min-w-0 lifts that limit. The button needs the opposite, so it keeps its text no matter how tight things get. Almost every broken navbar you have seen is missing one of these two.

Wrapping and small screens

A row of five items will not fit a phone. Add flex-wrap and the items flow onto the next line instead of shrinking, and pair it with a gap so the wrapped rows stay readable. When you want a controlled layout rather than a natural one, the responsive prefixes from the grid and breakpoints guide work identically on flex utilities.

<div class="flex flex-wrap items-center gap-3">
  <button class="rounded-md bg-teal-600 px-4 py-2 text-white">Save</button>
  <button class="rounded-md border border-slate-300 px-4 py-2">Cancel</button>
  <span class="ml-auto text-sm text-slate-500">Autosaved</span>
</div>

ml-auto is worth knowing on its own. Inside a flex row it pushes everything after it to the far side, which is a compact way to right-align one item without justifying the whole row.

A card footer that behaves

Putting it together gives the layout that appears in nearly every dashboard: content on top, then a footer line with a label on the left and an action on the right, stacked on a small screen.

<div class="flex flex-col gap-6 rounded-xl bg-white p-6 shadow">
  <div>
    <h3 class="text-lg font-semibold text-slate-900">Usage this month</h3>
    <p class="mt-1 text-sm text-slate-600">1,284 requests across 3 projects.</p>
  </div>
  <div class="flex flex-wrap items-center justify-between gap-3 border-t border-slate-200 pt-4">
    <span class="text-sm text-slate-500">Resets in 12 days</span>
    <a href="#" class="font-medium text-teal-600 hover:underline">View details</a>
  </div>
</div>

The outer container is flex-col so the sections stack and the footer sits at the bottom whatever the content height. The footer is a plain row that wraps, so on a narrow phone the label and the link move to separate lines instead of colliding.

Flex or grid?

A rule of thumb that saves time: use flex when you are laying out items inside one component — a header row, a button group, a footer. Use grid when you are laying out the page or a set of equal cards, because grid-cols-3 says what you mean in one class. Flex is for relationships between siblings; grid is for the shape of the container. When both work, flex needs fewer decisions.

Frequently asked questions

What is the difference between justify and items in Tailwind?

justify-* works on the main axis, the direction items flow in. items-* works on the cross axis, the other one. In a row, justify spreads left to right and items moves items up and down.

Why does my flex row overflow on mobile?

Usually a child refuses to shrink. Add min-w-0 to the flexible child and shrink-0 to the ones that must keep their size, or add flex-wrap so items move to a new line.

Should I use flexbox or grid for a card layout?

Use grid for the set of cards, with grid-cols-1 md:grid-cols-3 and a gap. Use flex for the contents inside each card, such as the title row and the footer.

Last updated on · Written by