Flexbox vs Grid — choosing the right tool
You already know Flexbox. It's great for aligning items in a single direction — a row of buttons, a vertical stack, a nav bar. But when you need to place things in two dimensions simultaneously — rows AND columns — that's what CSS Grid is built for.
-
Flexbox — one-dimensional. Items flow in a row or a column. Great for: navbars, button groups, centered content, card headers.
-
CSS Grid — two-dimensional. You define explicit rows and columns. Great for: page layouts, image galleries, dashboards, anything with structure in both axes.
Grid basics — columns, rows, gaps
.grid {
display: grid;
/* Define 3 equal columns */
grid-template-columns: 1fr 1fr 1fr;
/* Shorthand: repeat(3, 1fr) */
/* Define rows (usually auto-sized) */
grid-template-rows: auto;
/* Gap between cells */
gap: 24px;
/* Or: column-gap: 24px; row-gap: 16px; */
}
/* Responsive: as many columns as fit at 280px each */
.responsive-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 20px;
}
1fr?fr stands for "fraction" — a fractional unit of the available space. 1fr 1fr 1fr means three equal columns sharing all available width. 2fr 1fr means the first column gets twice as much space as the second.Placing items precisely
By default, grid items flow automatically into cells. But you can also tell items exactly where to go — which column to start at, how many columns to span.
/* A featured card that spans 2 columns */
.card--featured {
grid-column: span 2;
}
/* Place precisely: column 1 through 3, row 1 */
.hero {
grid-column: 1 / 3;
grid-row: 1;
}
/* Named grid areas — the most readable approach */
.layout {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 280px 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
.site-header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main-content{ grid-area: main; }
.site-footer { grid-area: footer; }
CSS Transitions — deliberate motion
Transitions animate the change between two CSS states. When a property changes (on hover, on focus, on class toggle), instead of jumping, it smoothly interpolates.
.card {
background: #111;
transform: translateY(0);
box-shadow: none;
/* Animate: property duration easing */
transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.15s ease;
}
.card:hover {
background: #161616;
transform: translateY(-4px);
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
}
/* Common easing curves */
/* ease — slow start, fast middle, slow end (default feel) */
/* ease-out — fast start, slow end (elements arriving) */
/* ease-in — slow start, fast end (elements leaving) */
/* cubic-bezier(0.34, 1.56, 0.64, 1) — springy overshoot */
transform and opacity when possiblewidth, height, margin, or top/left forces the browser to recalculate layout on every frame — expensive. transform and opacity are GPU-accelerated. Use transform: translateY(-4px) instead of margin-top: -4px.Keyframe animations — full control
Transitions animate between two states. Keyframe animations let you define multiple states at percentage points along a timeline.
/* Define the animation */
@keyframes fadeSlideUp {
from {
opacity: 0;
transform: translateY(16px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05); }
}
/* Apply it */
.card {
/* name duration easing fill-mode */
animation: fadeSlideUp 0.4s ease-out both;
}
.notification-dot {
animation: pulse 2s ease-in-out infinite;
}
/* Stagger animations with delay */
.card:nth-child(1) { animation-delay: 0ms; }
.card:nth-child(2) { animation-delay: 80ms; }
.card:nth-child(3) { animation-delay: 160ms; }
-
1The starter code has 4 product cards in a static flex layout. Convert it to CSS Grid with
display: gridandgrid-template-columns: repeat(auto-fill, minmax(220px, 1fr)). -
2Add a hover effect using
transition: the card should lift up withtransform: translateY(-6px)and get a shadow. Use a smooth easing. -
3Bonus: Add a
@keyframes fadeSlideUpanimation so each card fades in when the page loads. Useanimation-delayto stagger them.
- Flexbox for one dimension (rows OR columns); Grid for two dimensions (rows AND columns simultaneously)
repeat(auto-fill, minmax(280px, 1fr))is the magic responsive grid formula — no media queries needed- Named grid areas (
grid-template-areas) make complex layouts readable and maintainable - Only animate
transformandopacity— they're GPU-accelerated and won't cause jank - Stagger animation delays (
animation-delay) to create sequence effects without JavaScript