- Author
- app-hacks
- Published
CSS / Tailwind CSS / Responsive Design
Practical Flexbox vs. CSS Grid: Headers and Card Layouts
Use Flexbox for one-dimensional headers and CSS Grid for two-dimensional card lists, with Tailwind examples and mobile-safe layout constraints.
Flexbox and Grid are complementary. Flexbox arranges items along one primary axis and manages spacing or wrapping. Grid defines rows and columns together. Choosing by dimensional constraint reduces manual width calculations and media queries.
Use Flexbox for a header
<header class="site-header">
<a class="brand" href="/">app-hacks</a>
<nav aria-label="Main navigation"><ul class="nav-list">
<li><a href="/en/blog/">Articles</a></li><li><a href="/en/about/">About</a></li>
</ul></nav>
</header>
.site-header { display: flex; align-items: center; justify-content: space-between; gap: 1.25rem; min-height: 4rem; }
.nav-list { display: flex; align-items: center; gap: .75rem; margin: 0; padding: 0; list-style: none; }
The logo and navigation use their intrinsic widths while space-between distributes the remainder. The same structure in Tailwind is direct:
<header class="flex min-h-16 items-center justify-between gap-5">
<a class="text-lg font-bold" href="/en/">app-hacks</a>
<nav aria-label="Main navigation"><ul class="flex items-center gap-3">
<li><a class="px-3 py-2" href="/en/blog/">Articles</a></li>
<li><a class="px-3 py-2" href="/en/about/">About</a></li>
</ul></nav>
</header>
On narrow screens, first reduce excessive gaps or allow wrapping. A hamburger menu adds JavaScript and accessibility states, so introduce it only when the number of items requires it.
Use Grid for card lists
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
gap: 1.5rem;
}
.card { min-width: 0; border: 1px solid #e4eaf0; border-radius: 1rem; background: #fff; padding: 1.5rem; }
auto-fit creates as many columns as fit and collapses empty tracks. minmax(min(100%, 18rem), 1fr) can shrink below 18rem with the container; plain minmax(18rem, 1fr) may overflow on small screens.
For explicit breakpoints:
<section class="grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3">
<article class="min-w-0 rounded-2xl border border-slate-200 bg-white p-6">
<h2 class="text-xl font-bold">Card title</h2>
<p class="mt-3 leading-7 text-slate-600">A concise description.</p>
</article>
</section>
Start at one column and add columns only as space increases. Let grid tracks decide width instead of assigning a fixed card width.
Combine outer and inner layouts
<article class="grid gap-4 rounded-2xl border border-slate-200 p-6">
<div class="flex flex-wrap items-center gap-x-3 gap-y-2 text-sm text-slate-500">
<time datetime="2026-09-07">Sep 7, 2026</time>
<span class="rounded-md bg-sky-50 px-2 py-1 text-sky-700">CSS</span>
</div>
<h2 class="text-xl font-bold">Choosing Flexbox and Grid</h2>
<p class="leading-7 text-slate-600">Choose from the container's primary constraint.</p>
</article>
An outer Grid and inner Flexbox are natural: each container only controls its direct children.
Avoid brittle constraints
Long URLs or code can force flex children wider than their container. Apply min-width: 0 (min-w-0) where needed and an appropriate wrapping rule. Avoid fixed card heights because text length and user font scaling vary. Let content grow; align bottom actions inside the card with an internal grid or column flex layout and margin-top: auto.
Absolute positioning removes content from normal flow and should be limited to true overlays such as corner badges. The deciding factor is the constraint: use Flexbox for a one-axis flow and Grid when column widths and multiple rows must align.