# CSS Layout Systems — Deep Dive
> Comprehensive research on CSS Grid, Flexbox, Container Queries, and advanced layout techniques.
---
## 1. CSS Grid — The Most Powerful 2D Layout System
### `grid-template-columns` / `grid-template-rows`
```css
/* Fixed + fractional */
.grid {
display: grid;
grid-template-columns: 200px 1fr 2fr;
grid-template-rows: auto 1fr auto;
}
/* Mixed units */
.grid {
grid-template-columns: minmax(200px, 300px) 1fr 1fr;
}
```
### `fr` Units — Fractional Free Space
`fr` divides *remaining* space after definite-sized tracks are accounted for.
```css
.grid {
/* 200px fixed, remaining space split 1:2:1 */
grid-template-columns: 200px 1fr 2fr 1fr;
}
```
### `repeat()` — Compact Track Repetition
```css
/* Simple repeat */
.grid { grid-template-columns: repeat(3, 1fr); }
/* Alternating pattern */
.grid { grid-template-columns: repeat(6, 1fr 2fr); }
/* Named lines inside repeat */
.grid {
grid-template-columns: repeat(4, [col-start] 1fr [col-end]);
}
```
### `minmax()` — Flexible Track Sizing
```css
.grid {
/* Each column: minimum 200px, grows to fill */
grid-template-columns: repeat(3, minmax(200px, 1fr));
}
/* CRITICAL: minmax(0, 1fr) prevents overflow in fr containers */
.grid-cell { grid-column: span 2; }
.grid { grid-template-columns: minmax(0, 1fr) 300px; }
```
### `auto-fill` / `auto-fit` — Responsive Without Media Queries
```css
/* auto-fill: creates tracks even if empty */
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}
/* auto-fit: collapses empty tracks */
.gallery-fit {
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
/* 1 item = full width, 2 items = 50/50, etc. */
}
```
**Complete responsive card grid — zero media queries:**
```css
.card-grid {
display: grid;
gap: 1rem;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
.card {
background: #f0f0f0;
padding: 1.5rem;
border-radius: 8px;
}
```
### `grid-template-areas` — Named Visual Layout
```css
.layout {
display: grid;
grid-template-columns: 250px 1fr 200px;
grid-template-rows: 60px auto 40px;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
```
### Grid Placement — `grid-column` / `grid-row`
```css
/* Span multiple tracks */
.hero {
grid-column: 1 / span 3;
grid-row: 1 / 2;
}
/* Shorthand */
.wide { grid-column: span 2; }
.tall { grid-row: 1 / span 2; }
```
### `dense` Packing — Fill Gaps Automatically
```css
.grid {
grid-auto-flow: dense; /* Fill holes left by spanning items */
}
.large { grid-column: span 2; }
/* ⚠️ Reorders visual output — don't use for time-ordered data */
```
---
## 2. Subgrid (2024+)
Nested grids that inherit parent track definitions.
### Card Alignment With Subgrid
```css
/* Without subgrid — internal elements misalign across cards */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1.5rem;
}
.card { display: grid; /* creates own columns */ }
/* ✅ With subgrid — all cards share column/row tracks */
.card {
display: grid;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
}
```
### Subgrid Navigation
```css
.nav {
display: grid;
grid-template-columns: repeat(4, 1fr);
}
.nav-item {
display: grid;
grid-template-columns: subgrid;
grid-template-rows: auto auto; /* icon row + label row */
align-items: center;
}
```
> **Support:** Chrome 117+, Firefox 113+, Safari 17.2+
---
## 3. Flexbox — 1D Layout Mastery
### `flex: grow shrink basis`
```css
.item-a { flex: 1 0 200px; } /* grow=1, shrink=0, base=200px */
.item-b { flex: 2 0 auto; } /* grow=2, base=content size */
.item-c { flex: 0 1 auto; } /* doesn't grow, can shrink */
/* Common shorthands */
.item-fill { flex: 1; } /* = 1 1 0% */
.item-rigid { flex: 0 0 auto; } /* fixed to content size */
```
### The `min-width: 0` Trick
Flex items default to `min-width: auto`, preventing shrink below content.
```css
/* ❌ Text overflows */
.flex-item { flex: 1; }
/* ✅ Allow shrinking */
.flex-item {
flex: 1;
min-width: 0; /* ← THE FIX */
overflow: hidden;
}
```
**Common in nav bars:**
```css
.nav { display: flex; align-items: center; }
.nav-brand { flex-shrink: 0; }
.nav-search { flex: 1; min-width: 0; }
.nav-search input { width: 100%; }
```
### `align-items` / `justify-content` Values
```css
.container {
display: flex;
height: 400px;
justify-content: space-evenly; /* flex-start | flex-end | center | space-between | space-around | space-evenly */
align-items: center; /* stretch | center | flex-start | flex-end | baseline */
}
/* Override for single item */
.special { align-self: stretch; }
```
### Holy Grail Layout with Flexbox
```css
.page {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.main { display: flex; flex: 1; } /* pushes footer down */
.sidebar { flex: 0 0 250px; }
.content { flex: 1; min-width: 0; }
```
---
## 4. Container Queries (2024+)
Components respond to *their container*, not the viewport.
### Setup
```css
.card-container {
container-type: inline-size; /* query width */
container-name: card; /* optional name */
}
```
### Basic Container Query
```css
.card-container { container-type: inline-size; }
.card-title { font-size: 1rem; }
@container (min-width: 400px) {
.card-title { font-size: 1.5rem; }
.card-image { display: block; max-height: 200px; }
}
@container (max-width: 399px) {
.card-image { display: none; }
}
```
### Container Query Units
```css
.hero { container-type: inline-size; }
.hero-title {
font-size: clamp(1.5rem, 8cqi, 4rem); /* cqi = container inline size */
}
```
| Unit | Description |
|------|-------------|
| `cqi` | Container inline size (width) |
| `cqb` | Container block size (height) |
| `cqw` | Container width |
| `cqh` | Container height |
### Responsive Card Component
```css
.card-container { container-type: inline-size; }
.card { display: flex; flex-direction: column; }
.card-img { width: 100%; height: 150px; object-fit: cover; }
@container (min-width: 500px) {
.card { flex-direction: row; }
.card-img { width: 180px; height: auto; }
}
```
---
## 5. CSS Pseudo-elements
### `::before` / `::after` — Decorative Content
```css
/* Tooltip from data attribute */
.tooltip { position: relative; border-bottom: 1px dashed #666; }
.tooltip::after {
content: attr(data-tooltip);
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
padding: 4px 8px;
background: #333;
color: #fff;
border-radius: 4px;
white-space: nowrap;
opacity: 0;
transition: opacity 0.2s;
pointer-events: none;
}
.tooltip:hover::after { opacity: 1; }
```
### Drop Caps
```css
.article p:first-of-type::first-letter {
float: left;
font-size: 3.5rem;
line-height: 0.8;
margin-right: 0.1em;
font-weight: bold;
color: #1e40af;
}
```
### `::placeholder`
```css
input::placeholder {
color: #9ca3af;
font-style: italic;
opacity: 1;
}
```
### `::backdrop` — Native Modal Overlay
```css
dialog::backdrop {
background: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(4px);
}
```
---
## 6. CSS Counters — Auto-Numbering Without JS
```css
body { counter-reset: chapter; }
h2 { counter-reset: section; }
h2::before {
counter-increment: chapter;
content: counter(chapter) ". ";
}
h3::before {
counter-increment: section;
content: counter(chapter) "." counter(section) " ";
}
/* counters() — automatic nested numbering */
ol { counter-reset: item; list-style: none; }
ol > li::before {
counter-increment: item;
content: counters(item, ".", decimal) ". ";
}
/* Output: 1., 2., 2.1., 2.2., 2.2.1. */
```
### Numbered Steps
```css
.step-list { counter-reset: step; list-style: none; padding: 0; }
.step-list li {
counter-increment: step;
position: relative;
padding-left: 3rem;
margin-bottom: 1.5rem;
}
.step-list li::before {
content: counter(step);
position: absolute;
left: 0; top: 0;
width: 2rem; height: 2rem;
background: #6366f1;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
```
---
## 7. Multi-Column Layout
```css
.newspaper {
column-count: 3;
column-gap: 2rem;
column-rule: 1px solid #e5e7eb;
}
.article { columns: 250px; } /* auto-fit ~250px columns */
/* balance (default) vs fill */
.newspaper-balance { column-fill: balance; }
.newspaper-fill { column-fill: fill; }
/* Prevent elements from splitting across columns */
.card { break-inside: avoid; }
/* Span heading across all columns */
.newspaper h2 { column-span: all; }
```
---
## 8. Positioning
### `position: sticky`
```css
.sticky-header {
position: sticky;
top: 0;
background: white;
z-index: 10;
}
/* ⚠️ Parent must have overflow: visible (default) */
```
### Sticky Sidebar
```css
.sidebar {
position: sticky;
top: 1rem;
align-self: start;
max-height: calc(100vh - 2rem);
overflow-y: auto;
}
```
### Sticky Table Headers
```css
.sticky-table th {
position: sticky;
top: 0;
background: #1e40af;
z-index: 1;
}
/* Sticky first column */
.sticky-table td:first-child,
.sticky-table th:first-child {
position: sticky;
left: 0;
z-index: 2;
}
```
### `inset` Shorthand
```css
.overlay {
position: fixed;
inset: 0; /* = top:0; right:0; bottom:0; left:0; */
}
.modal {
position: fixed;
inset: 10vh 2rem auto 2rem; /* top, right, bottom, left */
}
```
---
## 9. Viewport Units
### Traditional
| Unit | Description |
|------|-------------|
| `vw` | 1% of viewport width |
| `vh` | 1% of viewport height |
| `vmin` | 1% of smaller dimension |
| `vmax` | 1% of larger dimension |
```css
.hero { height: 100vh; }
.square { width: 50vmin; height: 50vmin; }
.title { font-size: clamp(2rem, 5vw, 5rem); }
```
### Dynamic Viewport Units (Mobile)
| Unit | Description |
|------|-------------|
| `svh` | Smallest (address bar visible) |
| `lvh` | Largest (address bar hidden) |
| `dvh` | Dynamic (adjusts live) |
```css
.modal-fullscreen {
height: 100dvh; /* live-adjusts with address bar */
min-height: 100svh; /* never smaller than smallest */
}
/* Full-page app */
.app { height: 100dvh; display: flex; flex-direction: column; }
```
### `env()` — Safe Area Insets
```css
/* iPhone notch compatibility */
body {
padding-top: env(safe-area-inset-top);
padding-bottom: env(safe-area-inset-bottom);
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
}
```
---
## Quick Reference: When to Use What
| Problem | Best Tool |
|---------|-----------|
| Page-level 2D layout | **CSS Grid** |
| Component 1D layout | **Flexbox** |
| Responsive card grids | **Grid `auto-fit` + `minmax()`** |
| Nested aligned grids | **Subgrid** |
| Component-level responsiveness | **Container Queries** |
| Auto-numbering | **CSS Counters** |
| Magazine layout | **Multi-column** |
| Sticky scroll headers | **`position: sticky`** |
| Full-viewport overlay | **`inset: 0`** |
| Mobile full-height | **`dvh` + `svh`** |
| Decorative overlays | **`::before` / `::after`** |
| Drop caps | **`::first-letter`** |