# 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`** |
