# Code Reference — CSS

_57 pages_

---
# CSS (/docs/css)



# CSS [#css]

Layout, cascade, modern CSS.

Browse the sidebar for every cheat sheet in this section.

## Sections [#sections]

* [Examples](./examples)


---

# Adaptive design (/docs/css/adaptive)



# Adaptive design [#adaptive-design]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Adaptive design adjusts layout, typography, and interaction patterns to the viewport, input method, and user preferences. In CSS this is driven by media queries, container queries, and preference queries (`prefers-*`). Use it when a single fixed layout cannot serve phones, tablets, desktops, and accessibility needs equally well.

Prefer fluid units and container queries for component-level adaptation; reserve viewport media queries for page chrome and major breakpoints.

## 🔧 Core concepts [#-core-concepts]

### Media features [#media-features]

| Feature                             | Typical use                 |
| ----------------------------------- | --------------------------- |
| `width` / `min-width` / `max-width` | Viewport breakpoints        |
| `height` / `orientation`            | Tall vs wide layouts        |
| `hover` / `pointer`                 | Touch vs mouse affordances  |
| `prefers-reduced-motion`            | Disable or soften animation |
| `prefers-color-scheme`              | Light / dark themes         |
| `prefers-contrast`                  | High-contrast adjustments   |

### Breakpoint pattern [#breakpoint-pattern]

```css
/* Mobile-first: base styles, then enhance */
.card { padding: 1rem; }

@media (min-width: 48rem) {
  .card { padding: 1.5rem; display: grid; grid-template-columns: 1fr 1fr; }
}

@media (min-width: 80rem) {
  .card { grid-template-columns: 1fr 1fr 1fr; }
}
```

### Container queries [#container-queries]

| Property / rule               | Role                                      |
| ----------------------------- | ----------------------------------------- |
| `container-type: inline-size` | Establish a size query container          |
| `container-name`              | Name a container for targeted queries     |
| `@container (min-width: …)`   | Style based on parent width, not viewport |

### Logical & fluid sizing [#logical--fluid-sizing]

| Approach      | Example                                                |
| ------------- | ------------------------------------------------------ |
| Fluid type    | `font-size: clamp(1rem, 0.9rem + 0.5vw, 1.25rem)`      |
| Fluid space   | `padding-inline: clamp(1rem, 4vw, 3rem)`               |
| Logical props | `margin-inline`, `padding-block`, `inset-inline-start` |

## 💡 Examples [#-examples]

### Viewport media query (mobile-first) [#viewport-media-query-mobile-first]

```css
.nav {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

@media (min-width: 64rem) {
  .nav {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}
```

### Container query card [#container-query-card]

```html
<div class="card-shell">
  <article class="card">…</article>
</div>
```

```css
.card-shell {
  container-type: inline-size;
  container-name: card;
}

.card { display: block; }

@container card (min-width: 28rem) {
  .card {
    display: grid;
    grid-template-columns: 8rem 1fr;
    gap: 1rem;
  }
}
```

### Input and motion preferences [#input-and-motion-preferences]

```css
/* Coarse pointer: larger hit targets */
@media (pointer: coarse) {
  .btn { min-block-size: 2.75rem; padding-inline: 1.25rem; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
```

### Fluid layout without breakpoints [#fluid-layout-without-breakpoints]

```css
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: clamp(0.75rem, 2vw, 1.5rem);
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Designing desktop-first and only shrinking with `max-width` queries often creates brittle overrides.
* Using only viewport queries for reusable components breaks when the same card sits in a narrow sidebar.
* Ignoring `prefers-reduced-motion` and `prefers-color-scheme` harms accessibility and OS integration.
* Hard-coding many pixel breakpoints instead of a small set plus fluid `clamp()` / `minmax()`.
* Testing only by resizing a desktop window—verify real devices, zoom, and landscape orientation.

## 🔗 Related [#-related]

* [Flexbox](/docs/css/flex)
* [CSS Grid](/docs/css/grid)
* [Positioning](/docs/css/position)
* [Scroll](/docs/css/scroll)


---

# Animation (/docs/css/animation)



# Animation [#animation]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

CSS animations change property values over time using `@keyframes` and the `animation` longhands. Use them for attention, state feedback, and ambient motion—not for continuous layout thrashing. Prefer transitions for simple A→B state changes; use keyframe animations when you need multi-step timelines, loops, or delayed sequences.

Always respect `prefers-reduced-motion` and keep animated properties on the compositor (`transform`, `opacity`) when possible.

## 🔧 Core concepts [#-core-concepts]

### Animation properties [#animation-properties]

| Property                    | Purpose                                                              |
| --------------------------- | -------------------------------------------------------------------- |
| `animation-name`            | Keyframes identifier                                                 |
| `animation-duration`        | Length of one cycle                                                  |
| `animation-timing-function` | Easing (`ease`, `cubic-bezier()`, `steps()`)                         |
| `animation-delay`           | Start offset                                                         |
| `animation-iteration-count` | `1`, `n`, or `infinite`                                              |
| `animation-direction`       | `normal` \| `reverse` \| `alternate` \| `alternate-reverse`          |
| `animation-fill-mode`       | `none` \| `forwards` \| `backwards` \| `both`                        |
| `animation-play-state`      | `running` \| `paused`                                                |
| `animation-composition`     | How multiple animations combine (`replace` \| `add` \| `accumulate`) |

Shorthand: `animation: name duration timing-function delay iteration-count direction fill-mode play-state`.

### Keyframes [#keyframes]

```css
@keyframes fade-up {
  from {
    opacity: 0;
    transform: translateY(0.5rem);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
```

Percent stops (`0%`, `50%`, `100%`) allow multi-step sequences. Omitted properties interpolate when possible.

### Performance notes [#performance-notes]

| Prefer                           | Avoid animating                                  |
| -------------------------------- | ------------------------------------------------ |
| `transform`, `opacity`           | `top` / `left` / `width` / `height`              |
| `translate` / `scale` / `rotate` | Frequent `box-shadow` / `filter` on large layers |
| `will-change` sparingly          | Permanent `will-change` on many nodes            |

## 💡 Examples [#-examples]

### Entrance animation [#entrance-animation]

```css
.toast {
  animation: fade-up 280ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes fade-up {
  from { opacity: 0; transform: translateY(0.75rem); }
  to   { opacity: 1; transform: translateY(0); }
}
```

### Infinite loader [#infinite-loader]

```css
.spinner {
  inline-size: 2rem;
  block-size: 2rem;
  border: 0.2rem solid color-mix(in oklab, CanvasText 20%, transparent);
  border-block-start-color: CanvasText;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}
```

### Staggered list with delays [#staggered-list-with-delays]

```css
.item {
  animation: fade-up 400ms ease both;
}

.item:nth-child(1) { animation-delay: 0ms; }
.item:nth-child(2) { animation-delay: 60ms; }
.item:nth-child(3) { animation-delay: 120ms; }
```

### Reduced motion fallback [#reduced-motion-fallback]

```css
@media (prefers-reduced-motion: reduce) {
  .toast,
  .spinner,
  .item {
    animation: none;
  }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Animating layout properties every frame causes reflow and jank; use transforms instead.
* Forgetting `animation-fill-mode: forwards` (or `both`) so the end state snaps back after the animation ends.
* Running `infinite` animations on off-screen content without pausing (`animation-play-state` or removing the class).
* Ignoring `prefers-reduced-motion`, which can make interfaces unusable for vestibular disorders.
* Overusing `will-change`, which can increase memory use and create unexpected stacking contexts.

## 🔗 Related [#-related]

* [Transforms](/docs/css/transform)
* [Hover](/docs/css/hover)
* [Effects](/docs/css/effects)
* [Scale](/docs/css/scale)


---

# Aspect Ratio (/docs/css/aspect-ratio)



# Aspect Ratio [#aspect-ratio]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`aspect-ratio` preserves a box’s width-to-height relationship (e.g. `16 / 9`) as the other dimension flexes. Replaces old padding-top hacks for media frames, embeds, and cards. Combine with `object-fit` for replaced content.

## 🔧 Core concepts [#-core-concepts]

* **Syntax**: `aspect-ratio: auto | <ratio>` e.g. `16 / 9`, `1`, `4 / 3`.
* **`auto`**: use intrinsic ratio of replaced elements when available.
* **Conflict**: if width, height, and ratio all set, browsers may ignore one per rules — prefer width + ratio or height + ratio.
* **Min/max**: `min-height` can override the ratio box.
* **With grid/flex**: ratio boxes as items work well for galleries.

```css
.video {
  aspect-ratio: 16 / 9;
  width: 100%;
  background: #000;
}
.video iframe {
  width: 100%;
  height: 100%;
  border: 0;
}
```

## 💡 Examples [#-examples]

```css
/* Square thumbs */
.thumb {
  aspect-ratio: 1;
  object-fit: cover;
  width: 100%;
}

/* Portrait card */
.poster {
  aspect-ratio: 2 / 3;
}

/* Prefer auto for images with intrinsic size */
img {
  max-width: 100%;
  height: auto;
  aspect-ratio: auto;
}

/* Grid gallery */
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
  gap: 1rem;
}
.gallery > * {
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

/* Fallback old hack (legacy) */
.legacy {
  height: 0;
  padding-top: 56.25%;
  position: relative;
}
```

```css
/* Explicit both dimensions wins over ratio in some cases — avoid */
```

## ⚠️ Pitfalls [#️-pitfalls]

* Setting both `width` and `height` plus `aspect-ratio` can produce surprising ignored values.
* Content taller than the ratio box overflows unless `overflow: hidden` / flex layout inside.
* Intrinsic `auto` ratio fails for empty containers — set an explicit ratio.
* SVGs without intrinsic sizing may need explicit ratio.
* Don’t use ratio alone for text-heavy cards without overflow plan.

## 🔗 Related [#-related]

* [object\_fit.md](/docs/css/object-fit) — fitting media
* [image.md](/docs/css/image) — images
* [box\_model.md](/docs/css/box-model) — sizing
* [grid.md](/docs/css/grid) — galleries
* [../Html/video\_audio.md](/docs/css/../html/video-audio) — media embeds


---

# Background (/docs/css/background)



# Background [#background]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Background properties paint behind an element’s content and padding (by default), including colors, images, gradients, and layered stacks. Use them for surfaces, hero imagery, patterns, and decorative layers without adding extra DOM nodes. Multiple backgrounds are listed comma-separated, drawn from top (first) to bottom (last).

Prefer modern color spaces (`oklch`, `color-mix`) and `background-size` / `background-position` for responsive imagery; use `image-set()` when serving resolution variants.

## 🔧 Core concepts [#-core-concepts]

### Core properties [#core-properties]

| Property                | Role                                                            |
| ----------------------- | --------------------------------------------------------------- |
| `background-color`      | Solid fill (shows through transparent images)                   |
| `background-image`      | URL, gradient, or `none` (stackable)                            |
| `background-position`   | Anchor of the image (`center`, `top right`, `%`, lengths)       |
| `background-size`       | `auto` \| `cover` \| `contain` \| `<w> <h>`                     |
| `background-repeat`     | `repeat` \| `no-repeat` \| `space` \| `round` \| axes           |
| `background-attachment` | `scroll` \| `fixed` \| `local`                                  |
| `background-origin`     | Positioning box: `padding-box` \| `border-box` \| `content-box` |
| `background-clip`       | Painting area; `text` for clipped text fills                    |
| `background-blend-mode` | How layers blend with each other / color                        |

Shorthand: `background: [layer], [layer], … / color` — color is listed last and is not layered the same way as images.

### Layering model [#layering-model]

```css
.hero {
  background:
    linear-gradient(to bottom, rgb(0 0 0 / 0.45), transparent 60%),
    url("/img/hero.jpg") center / cover no-repeat,
    oklch(0.25 0.02 250);
}
```

First layer paints on top. The final color acts as a fallback under all images.

### Clipping & text fills [#clipping--text-fills]

| Value                          | Effect                                     |
| ------------------------------ | ------------------------------------------ |
| `background-clip: border-box`  | Default paint into border edge             |
| `background-clip: padding-box` | Stop under the border                      |
| `background-clip: content-box` | Only content box                           |
| `background-clip: text`        | Fill glyphs (needs transparent text color) |

## 💡 Examples [#-examples]

### Cover photo with scrim [#cover-photo-with-scrim]

```css
.banner {
  min-block-size: 20rem;
  color: white;
  background:
    linear-gradient(180deg, rgb(0 0 0 / 0.55), rgb(0 0 0 / 0.2)),
    url("/media/banner.jpg") center / cover no-repeat;
}
```

### Pattern tile [#pattern-tile]

```css
.panel {
  background-color: oklch(0.97 0.01 100);
  background-image: url("/patterns/dots.svg");
  background-size: 1.5rem 1.5rem;
  background-repeat: repeat;
}
```

### Gradient text [#gradient-text]

```css
.brand {
  background-image: linear-gradient(90deg, #0ea5e9, #6366f1);
  background-clip: text;
  -webkit-background-clip: text; /* WebKit */
  color: transparent;
}
```

### Fixed parallax-style layer [#fixed-parallax-style-layer]

```css
.parallax {
  background-image: url("/img/texture.jpg");
  background-size: cover;
  background-attachment: fixed;
  background-position: center;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Putting `background-color` in the middle of a multi-layer shorthand can drop layers or confuse cascade order—keep color last.
* `background-attachment: fixed` is expensive and often broken or disabled on mobile browsers.
* Using `cover` without a sensible `background-position` crops important subject matter.
* Forgetting a solid `background-color` fallback when images fail or load slowly.
* Relying on `background` for meaningful content—screen readers and broken-image states won’t expose it; use `<img>` for content images.

## 🔗 Related [#-related]

* [Gradients](/docs/css/gradient)
* [Images](/docs/css/image)
* [Effects](/docs/css/effects)
* [Text](/docs/css/text)


---

# Box Model (/docs/css/box-model)



# Box Model [#box-model]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Every element box has content, padding, border, and margin. `box-sizing` controls whether `width`/`height` include padding and border. Mastering the box model prevents overflow surprises and layout math errors.

## 🔧 Core concepts [#-core-concepts]

* **Content box**: where text/replaced content sits.
* **Padding**: inside the border, clears content.
* **Border**: edge around padding.
* **Margin**: outside border; vertical margins may collapse.
* **`box-sizing: content-box`** (default): width = content only.
* **`box-sizing: border-box`**: width includes padding + border (recommended reset).
* **Outline** / **box-shadow**: don’t add to layout size.

```css
*,
*::before,
*::after {
  box-sizing: border-box;
}
.card {
  width: 320px;
  padding: 1rem;
  border: 2px solid #ccc;
  margin: 1rem auto;
}
```

## 💡 Examples [#-examples]

```css
/* Total footprint with border-box */
.box {
  box-sizing: border-box;
  width: 100%;
  padding: 16px;
  border: 4px solid;
} /* content shrinks; outer width stays 100% */

/* Margin collapse (siblings / parent-child) */
.section + .section {
  margin-top: 2rem; /* prefer gap in flex/grid */
}

/* Intrinsic sizing */
img {
  max-width: 100%;
  height: auto;
  display: block; /* remove inline gap */
}

/* Min/max */
.panel {
  min-width: 0; /* allow flex/grid children to shrink */
  max-width: 60ch;
}

/* Logical box */
.box {
  padding-inline: 1rem;
  padding-block: 0.5rem;
  margin-inline: auto;
}
```

```css
/* Debug */
* {
  outline: 1px solid rgb(255 0 0 / 0.2);
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Mixing `content-box` widths with padding causes overflow past the intended size.
* Vertical margin collapse can “eat” parent padding expectations — use flex `gap` or BFC (`overflow: auto`).
* Inline elements ignore `width`/`height` / vertical margins differently — use `inline-block` or block.
* `min-width: auto` on flex items prevents shrinking below content — set `min-width: 0`.
* Percentage padding resolves against **width** of containing block (including vertical padding %).

## 🔗 Related [#-related]

* [logical\_properties.md](/docs/css/logical-properties) — inline/block
* [overflow.md](/docs/css/overflow) — clipping
* [z\_index.md](/docs/css/z-index) — stacking
* [flex.md](/docs/css/flex) — flex sizing
* [grid.md](/docs/css/grid) — grid tracks


---

# Box Model Basics (/docs/css/box-model-basics)



# Box Model Basics [#box-model-basics]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Every element is a **box** made of content, padding, border, and margin. Layout spacing bugs almost always come from misunderstanding this model. Prefer `box-sizing: border-box` in modern pages.

## 🔧 Core concepts [#-core-concepts]

| Layer         | Role                                          |
| ------------- | --------------------------------------------- |
| Content       | Text or children; sized by `width` / `height` |
| Padding       | Space inside the border                       |
| Border        | Line around the padding                       |
| Margin        | Space outside the border                      |
| `content-box` | Default: width = content only                 |
| `border-box`  | Width includes padding + border               |

Vertical margins can **collapse** between stacked blocks.

## 💡 Examples [#-examples]

**See the box:**

```css
.card {
  width: 200px;
  padding: 16px;
  border: 4px solid #334155;
  margin: 24px;
  background: #f8fafc;
}
```

**border-box (recommended):**

```css
*,
*::before,
*::after {
  box-sizing: border-box;
}

.box {
  width: 200px;
  padding: 20px;
  border: 5px solid black;
  /* total outer width stays 200px with border-box */
}
```

**Margin vs padding:**

```css
.section {
  padding: 1rem; /* space inside, keeps background */
  margin-bottom: 2rem; /* space outside, separates from next block */
  background: #e2e8f0;
}
```

**Inspect in DevTools:** select an element and view the box model diagram.

## ⚠️ Pitfalls [#️-pitfalls]

* With `content-box`, `width: 200px` + padding + border grows past 200px.
* `margin: auto` horizontal centering needs a defined width on block boxes.
* Margin collapse can remove expected vertical gaps between siblings.
* Inline elements ignore `width`/`height` differently than block elements.

## 🔗 Related [#-related]

* [getting\_started.md](/docs/css/getting-started)
* [selectors\_basics.md](/docs/css/selectors-basics)
* [cascade\_basics.md](/docs/css/cascade-basics)
* [box\_model.md](/docs/css/box-model)


---

# Buttons (/docs/css/button)



# Buttons [#buttons]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Button styling covers native `<button>`, `[type="submit"]`, and link-buttons that must look and behave like controls. Good button CSS balances affordance (clear hit target, focus, hover/active), accessibility (contrast, keyboard focus), and consistency across variants (primary, secondary, ghost, danger). Prefer styling the real `<button>` element over clickable `<div>`s.

Use logical properties, relative units, and `:focus-visible` so mouse and keyboard users both get appropriate feedback.

## 🔧 Core concepts [#-core-concepts]

### Baseline reset & structure [#baseline-reset--structure]

| Concern   | Recommendation                                                         |
| --------- | ---------------------------------------------------------------------- |
| Font      | `font: inherit` so buttons match surrounding type                      |
| Cursor    | `cursor: pointer` on enabled controls                                  |
| Sizing    | Min hit area ≈ 44×44 CSS px on touch UIs                               |
| Alignment | `inline-flex` + `align-items` / `justify-content` for icon+label       |
| Disabled  | `disabled` attribute + `:disabled` styles; don’t rely on opacity alone |

### Interactive pseudo-classes [#interactive-pseudo-classes]

| Selector                               | When it applies                              |
| -------------------------------------- | -------------------------------------------- |
| `:hover`                               | Pointer over control (may be false on touch) |
| `:active`                              | During press                                 |
| `:focus-visible`                       | Keyboard (or UA-determined) focus ring       |
| `:disabled` / `[aria-disabled="true"]` | Non-interactive                              |
| `:focus-within`                        | Rarely needed on the button itself           |

### Design tokens (typical) [#design-tokens-typical]

| Token                         | Example role            |
| ----------------------------- | ----------------------- |
| `--btn-bg` / `--btn-fg`       | Fill and label          |
| `--btn-radius`                | Corner radius           |
| `--btn-pad-x` / `--btn-pad-y` | Internal spacing        |
| `--btn-border`                | Outline / ghost borders |

## 💡 Examples [#-examples]

### Solid primary button [#solid-primary-button]

```css
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.625rem 1rem;
  border: 1px solid transparent;
  border-radius: 0.5rem;
  font: inherit;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  background: oklch(0.55 0.18 250);
  color: white;
  transition: background-color 150ms ease, transform 100ms ease;
}

.btn:hover { background: oklch(0.48 0.18 250); }
.btn:active { transform: translateY(1px); }

.btn:focus-visible {
  outline: 2px solid oklch(0.7 0.15 250);
  outline-offset: 2px;
}

.btn:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}
```

### Ghost / secondary variants [#ghost--secondary-variants]

```css
.btn--ghost {
  background: transparent;
  color: oklch(0.4 0.12 250);
  border-color: color-mix(in oklab, currentColor 35%, transparent);
}

.btn--ghost:hover {
  background: color-mix(in oklab, currentColor 8%, transparent);
}
```

### Icon + label markup [#icon--label-markup]

```html
<button type="button" class="btn">
  <svg class="btn__icon" aria-hidden="true" focusable="false">…</svg>
  Save
</button>
```

```css
.btn__icon {
  inline-size: 1.125rem;
  block-size: 1.125rem;
  flex-shrink: 0;
}
```

### Full-width on small containers [#full-width-on-small-containers]

```css
.btn--block {
  display: flex;
  inline-size: 100%;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Removing `outline` without providing an equivalent `:focus-visible` style breaks keyboard users.
* Using `<a>` styled as a button for actions that don’t navigate—prefer `<button type="button">`.
* Setting only `opacity` on disabled buttons without `pointer-events` / `disabled`, so clicks still fire.
* Tiny tap targets (`padding: 2px 4px`) that fail mobile accessibility guidelines.
* Animating layout on press (`height` changes) instead of lightweight `transform` / color shifts.

## 🔗 Related [#-related]

* [Hover](/docs/css/hover)
* [Cursor](/docs/css/cursor)
* [Icons](/docs/css/icon)
* [Text fields](/docs/css/textfield)


---

# calc, min, max, clamp (/docs/css/calc-min-max-clamp)



# calc, min, max, clamp [#calc-min-max-clamp]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

CSS math functions compute lengths and numbers: `calc()` for expressions, `min()`/`max()` for bounds, and `clamp(min, preferred, max)` for fluid sizing. Essential for responsive type, gutters, and hybrid fixed/fluid layouts without many breakpoints.

## 🔧 Core concepts [#-core-concepts]

* **`calc(a + b)`**: `+`/`-` need spaces; `*`/`/` don’t mix incompatible units blindly.
* **`min(a, b, …)`*&#x2A;: smallest value; &#x2A;*`max`**: largest.
* **`clamp(MIN, VAL, MAX)`**: equivalent to `max(MIN, min(VAL, MAX))`.
* **Units**: mix `%`, `rem`, `vw`, `vh` inside calc carefully (browser resolves).
* **Nested**: functions can nest; variables welcome.
* **Also**: `abs()`, `round()`, `sin()`… in modern CSS (support varies).

```css
width: calc(100% - 2rem);
font-size: clamp(1rem, 0.5rem + 2vw, 1.5rem);
padding-inline: max(1rem, 3vw);
```

## 💡 Examples [#-examples]

```css
/* Fluid type */
:root {
  --step-0: clamp(1rem, 0.9rem + 0.4vw, 1.125rem);
}

/* Full-bleed breakout */
.full {
  width: 100vw;
  margin-inline: calc(50% - 50vw);
}

/* Sidebar layout */
.main {
  width: min(100%, 70rem);
  margin-inline: auto;
  padding-inline: max(1rem, calc((100% - 70rem) / 2));
}

/* Gap with vars */
.grid {
  gap: calc(var(--space, 0.5rem) * 2);
}

/* Prefer clamp over media queries for simple scales */
.hero-title {
  font-size: clamp(1.75rem, 1rem + 3vw, 3rem);
}

/* Keep readable measure */
.prose {
  max-width: min(65ch, 100%);
}
```

```css
/* Safe area */
padding-bottom: max(1rem, env(safe-area-inset-bottom));
```

## ⚠️ Pitfalls [#️-pitfalls]

* `calc(100% - 2)` is invalid — units required on both sides of `+`/`-`.
* Division by zero / invalid units make the declaration dropped.
* `clamp` preferred value can be written so min > max — browsers may swap or fail; keep MIN ≤ MAX.
* Mixing `vh` with mobile browser chrome causes jumpiness — consider `dvh`/`svh`.
* Don’t over-fluidize — extreme `vw` type harms zoom/a11y; prefer rem-based clamps.

## 🔗 Related [#-related]

* [variables.md](/docs/css/variables) — tokens in calc
* [media\_queries.md](/docs/css/media-queries) — when math isn’t enough
* [adaptive.md](/docs/css/adaptive) — responsive patterns
* [box\_model.md](/docs/css/box-model) — width math
* [font.md](/docs/css/font) — fluid type


---

# Cascade Basics (/docs/css/cascade-basics)



# Cascade Basics [#cascade-basics]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The **cascade** decides which CSS rule wins when several apply to the same element. Browsers combine origin, importance, **specificity**, and source order. Understanding this stops “why didn’t my style apply?” frustration.

## 🔧 Core concepts [#-core-concepts]

| Factor       | Simple takeaway                                        |
| ------------ | ------------------------------------------------------ |
| Importance   | `!important` beats normal rules (avoid while learning) |
| Specificity  | Id > class > type (roughly)                            |
| Source order | Later rule wins if specificity is equal                |
| Inheritance  | Some properties flow to children (`color`, `font`)     |
| Inline style | `style=""` is very specific                            |

When two class selectors conflict, the one that appears **last** in the CSS usually wins.

## 💡 Examples [#-examples]

**Source order:**

```css
.title {
  color: blue;
}
.title {
  color: crimson; /* wins */
}
```

**Specificity sketch:**

```css
p {
  color: black;
} /* type: low */
.note {
  color: green;
} /* class: medium */
#intro {
  color: purple;
} /* id: high */
```

```html
<p id="intro" class="note">Which color?</p>
<!-- purple — id wins -->
```

**Inheritance:**

```css
article {
  color: #334155;
  font-family: Georgia, serif;
}
/* paragraphs inside article inherit color/font unless overridden */
```

**Equal specificity — last wins:**

```css
.btn {
  background: gray;
}
.btn {
  background: teal;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Fighting with `#id` and `!important` creates unmaintainable CSS.
* Browser DevTools “Computed” panel shows the winner — use it.
* Not all properties inherit (`margin` does not).
* Linked stylesheets order in HTML matters for equal-specificity ties.

## 🔗 Related [#-related]

* [selectors\_basics.md](/docs/css/selectors-basics)
* [box\_model\_basics.md](/docs/css/box-model-basics)
* [specificity.md](/docs/css/specificity)
* [cascade\_layers.md](/docs/css/cascade-layers)


---

# Cascade Layers (/docs/css/cascade-layers)



# Cascade Layers [#cascade-layers]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`@layer` groups style rules into named cascade layers so **order of layers** beats specificity across layers. Use layers to keep resets, tokens, components, and utilities predictable without specificity wars. Unlayered styles win over layered ones.

## 🔧 Core concepts [#-core-concepts]

* **Declare order**: `@layer reset, tokens, base, components, utilities;`
* **Assign**: `@layer components \{ .card \{\} \}` or `@layer components.card \{ \}`.
* **Import**: `@import "x.css" layer(components);`
* **Priority**: earlier layers lose to later layers (when both apply), regardless of specificity.
* **Unlayered**: strongest among normal author styles (before `!important` games).
* **`!important`**: reverses layer order in the important bucket.

```css
@layer reset, base, components, utilities;

@layer reset {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }
}
@layer components {
  .btn {
    padding: 0.5rem 1rem;
  }
}
@layer utilities {
  .p-0 {
    padding: 0;
  }
}
```

## 💡 Examples [#-examples]

```css
/* Nested layers */
@layer framework {
  @layer base {
    body {
      margin: 0;
    }
  }
  @layer components {
    .btn {
      color: white;
    }
  }
}
/* framework.base, framework.components */

/* Reordering via first declaration */
@layer a, b;
@layer b {
  .x {
    color: red;
  }
}
@layer a {
  .x {
    color: blue;
  }
} /* still loses — b is later */

/* Anonymous layer */
@layer {
  /* first anonymous */
}

/* Libraries first */
@layer vendor, app;
```

```css
/* Tip: put utilities last so .mt-0 beats components */
```

## ⚠️ Pitfalls [#️-pitfalls]

* Forgetting the initial `@layer a, b, c` order makes first-seen order define priority — declare explicitly.
* Unlayered CSS accidentally overrides everything layered — migrate carefully.
* `!important` in early layers becomes surprisingly strong — avoid.
* Layers don’t replace good naming — still organize files.
* DevTools cascade view is essential when debugging layer order.

## 🔗 Related [#-related]

* [specificity.md](/docs/css/specificity) — within a layer
* [reset\_normalize.md](/docs/css/reset-normalize) — reset layer
* [selectors.md](/docs/css/selectors) — selector design
* [variables.md](/docs/css/variables) — tokens layer
* [nesting.md](/docs/css/nesting) — nest inside layers


---

# Color Functions (/docs/css/color-functions)



# Color Functions [#color-functions]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Modern CSS colors use wide-gamut spaces and functions: `oklch`, `oklab`, `color()`, relative color syntax, and alpha with `/`. Prefer perceptually uniform spaces (`oklch`) for design systems and accessible gradients. Legacy `hex`, `rgb()`, `hsl()` remain fine.

## 🔧 Core concepts [#-core-concepts]

| Function                    | Notes                                     |
| --------------------------- | ----------------------------------------- |
| `oklch(L C H / A)`          | lightness, chroma, hue — great for themes |
| `oklab(...)`                | rectangular OKLab                         |
| `hsl()` / `hwb()`           | classic cylindrical                       |
| `rgb()` / `#rrggbbaa`       | sRGB                                      |
| `color(display-p3 ...)`     | wide gamut                                |
| `color-mix(in oklch, A, B)` | mix in a space                            |

* **Alpha**: `oklch(60% 0.1 250 / 0.8)` or `/ 80%`.
* **Relative**: `oklch(from var(--c) l c h)` / channel math.
* **Fallback**: provide hex/rgb before newer functions when needed.

```css
:root {
  --brand: oklch(62% 0.19 255);
  --brand-soft: color-mix(in oklch, var(--brand) 30%, white);
}
.button {
  background: var(--brand);
  color: oklch(99% 0 0);
}
```

## 💡 Examples [#-examples]

```css
/* Palette from one hue */
--h: 255;
--brand-1: oklch(95% 0.03 var(--h));
--brand-5: oklch(55% 0.18 var(--h));
--brand-9: oklch(30% 0.08 var(--h));

/* Relative color */
--accent: #3366ff;
--accent-dark: oklch(from var(--accent) calc(l * 0.8) c h);

/* Mix for hover */
.button:hover {
  background: color-mix(in oklch, var(--brand) 85%, black);
}

/* Gradients that don’t muddy */
background: linear-gradient(
  135deg,
  oklch(70% 0.15 30),
  oklch(65% 0.14 250)
);

/* P3 with fallback */
.hero {
  background: #ff3b00;
  background: color(display-p3 1 0.3 0);
}
```

```css
/* Contrast: still verify WCAG — oklch L helps but isn’t automatic */
```

## ⚠️ Pitfalls [#️-pitfalls]

* Out-of-gamut colors may map unexpectedly — check in target displays.
* Older Safari needed `-webkit` or lacked `color-mix` / relative syntax — progressive enhance.
* Mixing in sRGB often produces grayish midpoints — mix in `oklch`.
* `currentColor` and inheritance interact with computed colors carefully.
* Don’t assume L% maps 1:1 to WCAG contrast — measure.

## 🔗 Related [#-related]

* [variables.md](/docs/css/variables) — color tokens
* [gradient.md](/docs/css/gradient) — gradients
* [dark\_mode.md](/docs/css/dark-mode) — theme palettes
* [background.md](/docs/css/background) — backgrounds
* [filter\_backdrop.md](/docs/css/filter-backdrop) — filter color effects


---

# Multi-column layout (/docs/css/column)



# Multi-column layout [#multi-column-layout]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

CSS multi-column layout (`columns`, `column-count`, `column-width`, and related properties) flows content into newspaper-style columns. Use it for long prose, glossaries, or tag lists where vertical reading across balanced columns improves scanability. Prefer Flexbox or Grid when you need explicit item placement, equal card rows, or complex alignment—columns are for continuous flow, not component grids.

Columns fragment content automatically; control breaks with `break-inside`, `break-before`, and `break-after`.

## 🔧 Core concepts [#-core-concepts]

### Primary properties [#primary-properties]

| Property       | Role                                                  |
| -------------- | ----------------------------------------------------- |
| `column-count` | Ideal number of columns                               |
| `column-width` | Minimum comfortable column width; UA picks count      |
| `columns`      | Shorthand: `columns: <count> \|\| <width>`            |
| `column-gap`   | Gutters between columns (also `gap` in some contexts) |
| `column-rule`  | Vertical line between columns (`width style color`)   |
| `column-span`  | `all` lets a child span the full width                |
| `column-fill`  | `balance` (default in most UIs) \| `auto`             |

### Fragmentation controls [#fragmentation-controls]

| Property                       | Useful values                              |
| ------------------------------ | ------------------------------------------ |
| `break-inside`                 | `avoid` on headings, figures, cards        |
| `break-before` / `break-after` | `column`, `avoid-column`                   |
| `orphans` / `widows`           | Min lines left at bottom/top of a fragment |

### When to choose what [#when-to-choose-what]

| Need                  | Prefer                                 |
| --------------------- | -------------------------------------- |
| Flowing article text  | Multi-column                           |
| Card / gallery layout | Grid / Flex                            |
| Sidebar + main        | Grid / Flex                            |
| Masonry-like packing  | Grid (`masonry` where supported) or JS |

## 💡 Examples [#-examples]

### Responsive columns by width [#responsive-columns-by-width]

```css
.article-body {
  column-width: 18rem;
  column-gap: 2rem;
  column-rule: 1px solid color-mix(in oklab, CanvasText 15%, transparent);
  text-align: start;
}
```

### Fixed count with spanning heading [#fixed-count-with-spanning-heading]

```html
<section class="features">
  <h2 class="features__title">Highlights</h2>
  <p>…</p>
  <p>…</p>
</section>
```

```css
.features {
  columns: 3;
  column-gap: 1.5rem;
}

.features__title {
  column-span: all;
  margin-block-end: 1rem;
}
```

### Keep cards from splitting [#keep-cards-from-splitting]

```css
.card-list {
  columns: 2;
  column-gap: 1rem;
}

.card-list > .card {
  break-inside: avoid;
  margin-block-end: 1rem;
}
```

### Balance short content [#balance-short-content]

```css
.short-copy {
  columns: 2;
  column-fill: balance;
  max-block-size: 12rem; /* height can affect balancing */
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Using multi-column for a grid of independent cards without `break-inside: avoid`, which splits cards awkwardly.
* Setting both a high `column-count` and a large `column-width` so columns become unreadably narrow on small screens.
* Expecting Flex/Grid-like alignment control—columns don’t offer `justify-content` per “cell.”
* Forgetting that `column-span: all` only works for in-flow children of the multicol container.
* Overusing vertical rules that clash with nested borders or dark themes—tint with `color-mix` and test contrast.

## 🔗 Related [#-related]

* [CSS Grid](/docs/css/grid)
* [Flexbox](/docs/css/flex)
* [Text](/docs/css/text)
* [Adaptive design](/docs/css/adaptive)


---

# Container Queries (/docs/css/container-queries)



# Container Queries [#container-queries]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Container queries style descendants based on a **container’s** size (or style), not the viewport. Perfect for reusable components that adapt in sidebars vs main columns. Define a containment context with `container-type` / `container-name`, then `@container`.

## 🔧 Core concepts [#-core-concepts]

* **Context**: `container-type: inline-size | size | normal` (plus `container-name`).
* **Shorthand**: `container: name / inline-size;`.
* **Query**: `@container (min-width: 400px) \{ ... \}` or `@container card (min-width: 400px)`.
* **Units**: `cqw` `cqh` `cqi` `cqb` `cqmin` `cqmax` relative to container.
* **Style queries**: `@container style(--variant: compact)` (support evolving).
* **vs media**: media = viewport/device; container = parent component width.

```css
.card {
  container-type: inline-size;
  container-name: card;
}
@container card (min-width: 36rem) {
  .card-inner {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
}
```

## 💡 Examples [#-examples]

```css
.sidebar,
.main {
  container: layout / inline-size;
}

.widget {
  padding: 1rem;
}
@container layout (max-width: 300px) {
  .widget {
    font-size: 0.9rem;
  }
  .widget .meta {
    display: none;
  }
}

/* Fluid based on container */
@container (min-width: 20rem) {
  .title {
    font-size: clamp(1rem, 4cqi, 1.5rem);
  }
}

/* Named vs nearest */
@container (min-width: 500px) {
  /* nearest ancestor container */
}

/* Grid of cards each querying themselves */
.grid > * {
  container-type: inline-size;
}
```

```css
/* Need size queries for height */
.panel {
  container-type: size;
  height: 200px;
}
@container (min-height: 180px) {
  .panel .extra {
    display: block;
  }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Forgetting `container-type` means `@container` won’t match as expected.
* `inline-size` is most common; `size` also applies block-size containment (may affect sizing).
* Containment can influence layout — test overflow/sticky inside containers.
* Nested containers: queries use the correct named/nearest context — name them when ambiguous.
* Older browsers need fallbacks — progressive enhancement with default single-column layouts.

## 🔗 Related [#-related]

* [media\_queries.md](/docs/css/media-queries) — viewport queries
* [grid.md](/docs/css/grid) — responsive grids
* [adaptive.md](/docs/css/adaptive) — responsive strategy
* [calc\_min\_max\_clamp.md](/docs/css/calc-min-max-clamp) — cqi units
* [nesting.md](/docs/css/nesting) — nest @container


---

# Cursor (/docs/css/cursor)



# Cursor [#cursor]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The `cursor` property sets the mouse pointer appearance when hovering an element. It communicates interactivity (links, drag handles, resize edges) and system state (loading, not-allowed). Use it to reinforce affordances already present in markup and behavior—never as the only signal that something is clickable.

Touch devices often ignore cursor styles; always pair with clear visual design and adequate hit targets.

## 🔧 Core concepts [#-core-concepts]

### Common keyword values [#common-keyword-values]

| Value                  | Typical meaning               |
| ---------------------- | ----------------------------- |
| `auto` / `default`     | UA / arrow                    |
| `pointer`              | Link or button-like control   |
| `text`                 | Selectable text / inputs      |
| `move`                 | Draggable item                |
| `grab` / `grabbing`    | Grab affordance / active drag |
| `not-allowed`          | Action unavailable            |
| `wait` / `progress`    | Busy (blocking vs background) |
| `help`                 | Extra information available   |
| `crosshair`            | Precise selection             |
| `zoom-in` / `zoom-out` | Zoomable content              |

### Resize & edge cursors [#resize--edge-cursors]

| Value                                                     | Direction               |
| --------------------------------------------------------- | ----------------------- |
| `n-resize` `s-resize` `e-resize` `w-resize`               | Cardinal edges          |
| `ne-resize` `nw-resize` `se-resize` `sw-resize`           | Corners                 |
| `col-resize` / `row-resize`                               | Column / row separators |
| `ew-resize` / `ns-resize` / `nesw-resize` / `nwse-resize` | Bidirectional           |

### Custom images [#custom-images]

```css
.canvas {
  cursor: url("/cursors/pen.svg") 4 4, crosshair;
}
```

Syntax: `cursor: url(…) [x y], <fallback>`. Hotspot coordinates are optional; always provide a keyword fallback.

## 💡 Examples [#-examples]

### Interactive controls [#interactive-controls]

```css
a[href],
button:not(:disabled),
[role="button"]:not([aria-disabled="true"]) {
  cursor: pointer;
}

button:disabled,
[aria-disabled="true"] {
  cursor: not-allowed;
}
```

### Drag surface [#drag-surface]

```css
.draggable {
  cursor: grab;
}

.draggable:active,
.draggable.is-dragging {
  cursor: grabbing;
}
```

### Text vs chrome [#text-vs-chrome]

```css
.prose { cursor: auto; }
.prose code { cursor: text; }

.toolbar { cursor: default; }
.splitter { cursor: col-resize; }
```

### Loading overlay [#loading-overlay]

```css
.page.is-loading,
.page.is-loading * {
  cursor: progress;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Setting `cursor: pointer` on non-interactive elements without keyboard/semantics support misleads users.
* Omitting a fallback keyword after `url()` so broken custom cursors leave no pointer at all.
* Using `wait` for long operations that still allow interaction—prefer `progress` when the UI remains usable.
* Assuming cursor styles work on mobile; they usually don’t—design for touch without relying on them.
* Nesting conflicting cursors (`*` rules) so child controls never show `pointer` or `text`.

## 🔗 Related [#-related]

* [Buttons](/docs/css/button)
* [Hover](/docs/css/hover)
* [Text fields](/docs/css/textfield)
* [Effects](/docs/css/effects)


---

# Dark Mode (/docs/css/dark-mode)



# Dark Mode [#dark-mode]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Dark mode adapts UI colors for low-light preference or explicit theme toggles. Combine `prefers-color-scheme` with a class/`data-theme` override, CSS variables for tokens, and `color-scheme` for native form controls scrollbars.

## 🔧 Core concepts [#-core-concepts]

* **System**: `@media (prefers-color-scheme: dark)`.
* **Override**: `html[data-theme="dark"]` or `.dark` class (user choice).
* **`color-scheme: light dark`**: hints UA widgets.
* **Tokens**: redefine `--bg`, `--text`, `--border` per theme.
* **Images**: `picture` / CSS filters / separate assets for dark.
* **Meta**: `<meta name="color-scheme" content="light dark">`.

```css
:root {
  color-scheme: light dark;
  --bg: #fff;
  --text: #111;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #121212;
    --text: #f2f2f2;
  }
}
html[data-theme="dark"] {
  --bg: #121212;
  --text: #f2f2f2;
}
body {
  background: var(--bg);
  color: var(--text);
}
```

## 💡 Examples [#-examples]

```css
/* Explicit light lock */
html[data-theme="light"] {
  color-scheme: light;
  --bg: #fff;
  --text: #111;
}

/* Soft surfaces */
:root {
  --surface: color-mix(in oklch, var(--bg) 92%, var(--text));
}

/* Avoid pure #000/#fff if harsh — use near-black */
html[data-theme="dark"] {
  --bg: oklch(18% 0.02 260);
  --text: oklch(95% 0.01 260);
  --accent: oklch(75% 0.14 250);
}

/* Dim images slightly in dark */
html[data-theme="dark"] img:not([data-keep]) {
  opacity: 0.92;
}
```

```js
const root = document.documentElement;
const stored = localStorage.getItem("theme");
if (stored) root.dataset.theme = stored;
toggle.onclick = () => {
  const next = root.dataset.theme === "dark" ? "light" : "dark";
  root.dataset.theme = next;
  localStorage.setItem("theme", next);
};
```

## ⚠️ Pitfalls [#️-pitfalls]

* Flash of wrong theme — set theme early (inline script in `<head>`).
* Shadows and borders need retuning — light shadows disappear on dark bg.
* Don’t invert entire pages with `filter: invert()` — breaks images/videos.
* Contrast still must meet WCAG — dark gray on black often fails.
* Third-party embeds may stay light — plan letterboxing.

## 🔗 Related [#-related]

* [variables.md](/docs/css/variables) — tokens
* [color\_functions.md](/docs/css/color-functions) — oklch palettes
* [media\_queries.md](/docs/css/media-queries) — prefers-\*
* [../Javascript/DOM/media\_query\_list.md](/docs/css/../javascript/dom/media-query-list) — matchMedia
* [print.md](/docs/css/print) — force light for print


---

# Effects (/docs/css/effects)



# Effects [#effects]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Visual effects in CSS include `filter`, `backdrop-filter`, `box-shadow`, `text-shadow`, `mix-blend-mode`, and `opacity`. Use them for depth, glassmorphism, emphasis, and image treatment without editing assets. Prefer compositing-friendly effects and keep heavy filters off scrolling, full-viewport layers when performance matters.

`filter` affects the element and its contents; `backdrop-filter` samples what is *behind* the element (requires semi-transparent background to see the result).

## 🔧 Core concepts [#-core-concepts]

### Filter functions [#filter-functions]

| Function                                 | Role                                                    |
| ---------------------------------------- | ------------------------------------------------------- |
| `blur(r)`                                | Gaussian blur                                           |
| `brightness()` `contrast()` `saturate()` | Tonal adjustments                                       |
| `grayscale()` `sepia()` `hue-rotate()`   | Color treatments                                        |
| `opacity()`                              | Filter-level opacity (separate from `opacity` property) |
| `drop-shadow()`                          | Shadow that follows alpha shape (unlike `box-shadow`)   |
| `url(#svgFilter)`                        | Custom SVG filter reference                             |

Chain with spaces: `filter: brightness(1.1) contrast(1.05)`.

### Shadows & blending [#shadows--blending]

| Property                | Notes                                                           |
| ----------------------- | --------------------------------------------------------------- |
| `box-shadow`            | Shape follows border box; can be inset; multiple layers allowed |
| `text-shadow`           | Glyph shadows; no inset                                         |
| `mix-blend-mode`        | Blend element with backdrop                                     |
| `background-blend-mode` | Blend background layers                                         |
| `isolation: isolate`    | Create stacking context to contain blend modes                  |
| `opacity`               | Affects entire element including descendants                    |

### Backdrop filter checklist [#backdrop-filter-checklist]

1. Element needs a transparent or translucent background.
2. Something visible must sit behind it.
3. Often creates a containing stacking context; test overflow/positioning.

## 💡 Examples [#-examples]

### Soft elevation [#soft-elevation]

```css
.card {
  background: Canvas;
  border-radius: 0.75rem;
  box-shadow:
    0 1px 2px rgb(0 0 0 / 0.06),
    0 8px 24px rgb(0 0 0 / 0.08);
}
```

### Frosted glass panel [#frosted-glass-panel]

```css
.glass {
  background: rgb(255 255 255 / 0.55);
  border: 1px solid rgb(255 255 255 / 0.4);
  backdrop-filter: blur(12px) saturate(1.2);
  -webkit-backdrop-filter: blur(12px) saturate(1.2);
}
```

### Image hover treatment [#image-hover-treatment]

```css
.thumb img {
  filter: grayscale(0.2) brightness(0.95);
  transition: filter 200ms ease;
}

.thumb:hover img,
.thumb:focus-within img {
  filter: grayscale(0) brightness(1);
}
```

### Drop shadow on transparent PNG/SVG [#drop-shadow-on-transparent-pngsvg]

```css
.logo {
  filter: drop-shadow(0 4px 8px rgb(0 0 0 / 0.25));
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Applying large `blur()` or `backdrop-filter` on huge layers tanks scroll performance—limit size and animate sparingly.
* Expecting `box-shadow` to follow irregular transparent image edges—use `drop-shadow()` in `filter` instead.
* Setting `opacity` on a parent fades all children; prefer alpha on `background-color` / borders when only the surface should fade.
* Forgetting vendor-prefixed `-webkit-backdrop-filter` where still required.
* Using `mix-blend-mode` without `isolation`, causing unexpected blends with page chrome.

## 🔗 Related [#-related]

* [Background](/docs/css/background)
* [Hover](/docs/css/hover)
* [Animation](/docs/css/animation)
* [Images](/docs/css/image)


---

# Examples (/docs/css/examples)



# Examples [#examples]

CSS notes in **Examples**.


---

# Card Layout (/docs/css/examples/card-layout)



# Card Layout [#card-layout]

*CSS · Example / how-to*

***

## 📋 Overview [#-overview]

Lay out a responsive card grid with CSS Grid, consistent gaps, and a flexible media + body structure inside each card.

## 🔧 Core concepts [#-core-concepts]

| Piece                   | Role                     |
| ----------------------- | ------------------------ |
| `grid-template-columns` | Auto-fit columns         |
| `minmax`                | Fluid card width         |
| Flex column card        | Media on top, body grows |
| Aspect ratio            | Stable image boxes       |

## 💡 Examples [#-examples]

```html
<section class="card-grid">
  <article class="card">
    <img class="card-media" src="/img/a.jpg" alt="" />
    <div class="card-body">
      <h2>Title A</h2>
      <p>Short description.</p>
      <a href="/a">Read more</a>
    </div>
  </article>
  <article class="card">
    <img class="card-media" src="/img/b.jpg" alt="" />
    <div class="card-body">
      <h2>Title B</h2>
      <p>Short description.</p>
      <a href="/b">Read more</a>
    </div>
  </article>
</section>
```

```css
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1.25rem;
}

.card {
  display: flex;
  flex-direction: column;
  border: 1px solid #ddd;
  border-radius: 0.5rem;
  overflow: hidden;
  background: #fff;
}

.card-media {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  display: block;
}

.card-body {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1rem;
  flex: 1;
}

.card-body a {
  margin-top: auto;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Fixed pixel columns break on small phones — prefer `minmax` + `auto-fit`.
* Missing `alt` on meaningful images hurts accessibility; decorative images use `alt=""`.
* Uneven text lengths: push CTAs with `margin-top: auto` in a flex column.

## 🔗 Related [#-related]

* [Responsive nav](/docs/css/examples/responsive-nav)
* [Dark mode toggle](/docs/css/examples/dark-mode-toggle)


---

# Dark Mode Toggle (/docs/css/examples/dark-mode-toggle)



# Dark Mode Toggle [#dark-mode-toggle]

*CSS · Example / how-to*

***

## 📋 Overview [#-overview]

Implement light/dark themes with CSS custom properties, `prefers-color-scheme`, and a class or `data-theme` override.

## 🔧 Core concepts [#-core-concepts]

| Piece                  | Role                  |
| ---------------------- | --------------------- |
| Custom properties      | Tokenize colors       |
| `prefers-color-scheme` | System default        |
| `data-theme`           | Manual override       |
| Cascade                | Override beats system |

## 💡 Examples [#-examples]

```html
<html lang="en" data-theme="system">
  <body>
    <button type="button" id="theme-toggle">Toggle theme</button>
  </body>
</html>
```

```css
:root,
[data-theme="light"] {
  --bg: #f7f7f5;
  --fg: #1a1a1a;
  --accent: #0b6e4f;
}

[data-theme="dark"] {
  --bg: #121212;
  --fg: #f0f0f0;
  --accent: #5eead4;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #121212;
    --fg: #f0f0f0;
    --accent: #5eead4;
  }
}

body {
  background: var(--bg);
  color: var(--fg);
}

a {
  color: var(--accent);
}
```

```javascript
const root = document.documentElement;
const btn = document.querySelector("#theme-toggle");

btn.addEventListener("click", () => {
  const next = root.dataset.theme === "dark" ? "light" : "dark";
  root.dataset.theme = next;
  localStorage.setItem("theme", next);
});

const saved = localStorage.getItem("theme");
if (saved === "light" || saved === "dark") {
  root.dataset.theme = saved;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Hard-coded colors bypass tokens and break dark mode.
* Flash of wrong theme: set `data-theme` in a tiny inline script in `<head>`.
* Contrast: check WCAG for accent on both backgrounds.

## 🔗 Related [#-related]

* [Responsive nav](/docs/css/examples/responsive-nav)
* [Card layout](/docs/css/examples/card-layout)


---

# Responsive Nav (/docs/css/examples/responsive-nav)



# Responsive Nav [#responsive-nav]

*CSS · Example / how-to*

***

## 📋 Overview [#-overview]

Build a horizontal nav that collapses behind a details/summary (or checkbox) toggle on small screens using only CSS.

## 🔧 Core concepts [#-core-concepts]

| Piece                  | Role                   |
| ---------------------- | ---------------------- |
| Flexbox                | Align brand + links    |
| Media queries          | Switch layout by width |
| `:checked` / `details` | Toggle without JS      |
| `gap` / `wrap`         | Spacing without hacks  |

## 💡 Examples [#-examples]

**responsive\_nav.html + CSS:**

```html
<header class="site-header">
  <a class="brand" href="/">Docs</a>
  <details class="nav">
    <summary class="nav-toggle">Menu</summary>
    <ul class="nav-list">
      <li><a href="/guides">Guides</a></li>
      <li><a href="/api">API</a></li>
      <li><a href="/blog">Blog</a></li>
    </ul>
  </details>
</header>
```

```css
.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.75rem 1rem;
}

.nav-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
}

.nav-toggle {
  cursor: pointer;
  list-style: none;
}

.nav-toggle::-webkit-details-marker {
  display: none;
}

@media (min-width: 720px) {
  .nav {
    display: contents;
  }

  .nav-toggle {
    display: none;
  }

  .nav-list {
    flex-direction: row;
    margin: 0;
    align-items: center;
  }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `display: contents` removes the details box from layout — test focus order.
* Tiny tap targets on mobile — give summary enough padding.
* Fixed headers need `scroll-padding-top` so in-page anchors are not hidden.

## 🔗 Related [#-related]

* [Card layout](/docs/css/examples/card-layout)
* [Dark mode toggle](/docs/css/examples/dark-mode-toggle)


---

# Filter & Backdrop Filter (/docs/css/filter-backdrop)



# Filter & Backdrop Filter [#filter--backdrop-filter]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`filter` applies graphical effects (blur, brightness, drop-shadow…) to an element’s rendering — including descendants. `backdrop-filter` filters what is **behind** the element (frosted glass). Both can be expensive; use sparingly.

## 🔧 Core concepts [#-core-concepts]

| Function                                 | Role                                     |
| ---------------------------------------- | ---------------------------------------- |
| `blur(r)`                                | Gaussian blur                            |
| `brightness()` `contrast()` `saturate()` | tonal                                    |
| `grayscale()` `sepia()` `hue-rotate()`   | color                                    |
| `opacity()`                              | similar to `opacity` prop                |
| `drop-shadow()`                          | shadow following alpha (vs `box-shadow`) |
| `url(#svgFilter)`                        | SVG filter reference                     |

* **Chain**: `filter: blur(4px) brightness(1.1);`
* **Backdrop**: needs (semi)transparent background to see effect.
* **Containing block / stacking**: filters create containing blocks / stacking contexts.

```css
.avatar {
  filter: grayscale(1);
}
.avatar:hover {
  filter: none;
}
.glass {
  background: rgb(255 255 255 / 0.5);
  backdrop-filter: blur(12px) saturate(1.2);
}
```

## 💡 Examples [#-examples]

```css
/* Image treatment */
.hero img {
  filter: brightness(0.7) contrast(1.05);
}

/* Icon recolor trick (simple) */
.icon {
  filter: invert(1);
}

/* Drop shadow on transparent PNG */
.logo {
  filter: drop-shadow(0 4px 8px rgb(0 0 0 / 0.35));
}

/* Modal frosted overlay content */
.dialog {
  background: oklch(100% 0 0 / 0.7);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
}

/* Performance: prefer transform/opacity for motion; filter for static looks */
```

```css
@media (prefers-reduced-motion: reduce) {
  .blur-on-scroll {
    filter: none;
  }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `filter` on a parent blurs/repaints all descendants — isolate effects on leaf images when possible.
* `backdrop-filter` fails if no backdrop shows through (opaque bg) or browser lacks support — provide solid fallback bg.
* Creates a stacking context — can change `z-index` expectations.
* Animating heavy blurs is costly on low-end devices.
* `drop-shadow` ≠ `box-shadow` (follows alpha silhouette).

## 🔗 Related [#-related]

* [effects.md](/docs/css/effects) — shadows and visuals
* [transitions.md](/docs/css/transitions) — animating filters
* [background.md](/docs/css/background) — translucent backgrounds
* [z\_index.md](/docs/css/z-index) — stacking contexts
* [performance via blur](/docs/css/effects) — cost awareness


---

# Flexbox (/docs/css/flex)



# Flexbox [#flexbox]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Flexbox is a one-dimensional layout model for distributing space and aligning items along a row or column. Set `display: flex` or `inline-flex` on a container, then control direction, wrapping, alignment, and growth with flex properties. Use Flexbox for toolbars, navs, form rows, and equal-height media objects; use Grid when you need two-dimensional tracks or overlapping areas.

Main axis follows `flex-direction`; cross axis is perpendicular. Logical alignment (`start` / `end`) respects writing mode better than physical `left` / `right`.

## 🔧 Core concepts [#-core-concepts]

### Container properties [#container-properties]

| Property          | Common values                                                        | Role                    |
| ----------------- | -------------------------------------------------------------------- | ----------------------- |
| `flex-direction`  | `row` \| `row-reverse` \| `column` \| `column-reverse`               | Main axis               |
| `flex-wrap`       | `nowrap` \| `wrap` \| `wrap-reverse`                                 | Multi-line flex         |
| `flex-flow`       | shorthand of direction + wrap                                        |                         |
| `justify-content` | `start` `end` `center` `space-between` `space-around` `space-evenly` | Main-axis distribution  |
| `align-items`     | `stretch` `start` `end` `center` `baseline`                          | Cross-axis, one line    |
| `align-content`   | same family as justify                                               | Cross-axis when wrapped |
| `gap`             | `<row-gap> <column-gap>`                                             | Spacing between items   |

### Item properties [#item-properties]

| Property      | Role                                                             |
| ------------- | ---------------------------------------------------------------- |
| `flex-grow`   | Extra free space factor (default `0`)                            |
| `flex-shrink` | Shrink factor (default `1`)                                      |
| `flex-basis`  | Initial main size (`auto`, length, `%`, `content`)               |
| `flex`        | Shorthand: `grow shrink basis` — prefer `flex: 1` / `flex: none` |
| `align-self`  | Override `align-items` for one item                              |
| `order`       | Visual order (avoid for tab order / accessibility)               |

### Useful shorthand recipes [#useful-shorthand-recipes]

| Declaration       | Meaning                                        |
| ----------------- | ---------------------------------------------- |
| `flex: 1`         | `1 1 0%` — share space equally from zero basis |
| `flex: auto`      | `1 1 auto` — grow/shrink from content size     |
| `flex: none`      | `0 0 auto` — sized by content, don’t flex      |
| `flex: 0 0 12rem` | Fixed main size                                |

## 💡 Examples [#-examples]

### Toolbar [#toolbar]

```css
.toolbar {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding-inline: 1rem;
}

.toolbar__spacer {
  flex: 1;
}
```

### Media object [#media-object]

```css
.media {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
}

.media__body {
  flex: 1;
  min-inline-size: 0; /* allow text truncation */
}
```

### Wrapping chip list [#wrapping-chip-list]

```css
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
```

### Equal-height columns (row) [#equal-height-columns-row]

```css
.pricing {
  display: flex;
  gap: 1rem;
  align-items: stretch; /* default */
}

.pricing > .plan {
  flex: 1 1 0;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Forgetting `min-inline-size: 0` (or `min-width: 0`) on flex children so long text overflows instead of shrinking.
* Using `order` to reshuffle content without updating DOM order—keyboard and screen-reader order stay source-based.
* Mixing `justify-content: space-between` with `gap` expectations; gap is fixed space between items, not a substitute for margins in every case.
* Default `flex-shrink: 1` unexpectedly crushing icons—set `flex: none` or `flex-shrink: 0` on fixed chrome.
* Choosing Flexbox for a full page 2D layout that Grid expresses more clearly with template areas.

## 🔗 Related [#-related]

* [CSS Grid](/docs/css/grid)
* [Adaptive design](/docs/css/adaptive)
* [Positioning](/docs/css/position)
* [Buttons](/docs/css/button)


---

# Fonts (/docs/css/font)



# Fonts [#fonts]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Font CSS controls typeface selection, weight, style, size, and loading behavior. Modern stacks combine system fonts, self-hosted files via `@font-face`, and variable fonts for continuous weight/width axes. Good typography sets a clear hierarchy, readable line length, and resilient fallbacks when webfonts are slow or blocked.

Prefer `font-display` strategies that avoid invisible text, and use logical sizing (`rem`, `clamp`) for scalable UIs.

## 🔧 Core concepts [#-core-concepts]

### Key properties [#key-properties]

| Property              | Role                                                                       |
| --------------------- | -------------------------------------------------------------------------- |
| `font-family`         | Ordered stack; last should be generic (`sans-serif`, `serif`, `monospace`) |
| `font-size`           | Absolute, relative, or fluid (`clamp`)                                     |
| `font-weight`         | `100`–`900`, `normal`, `bold`, or variable axis                            |
| `font-style`          | `normal` \| `italic` \| `oblique`                                          |
| `font-stretch`        | Width (`condensed` … `expanded`)                                           |
| `font-variant-*`      | Caps, numeric figures, ligatures                                           |
| `line-height`         | Unitless preferred for inheritance                                         |
| `font`                | Shorthand (order-sensitive)                                                |
| `font-optical-sizing` | `auto` \| `none` for optical size axis                                     |
| `font-synthesis`      | Control fake bold/italic                                                   |

### @font-face essentials [#font-face-essentials]

```css
@font-face {
  font-family: "InterVar";
  src:
    url("/fonts/InterVar.woff2") format("woff2-variations"),
    url("/fonts/InterVar.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF; /* optional subset */
}
```

| `font-display` | Behavior                                             |
| -------------- | ---------------------------------------------------- |
| `swap`         | Show fallback immediately, swap in webfont           |
| `optional`     | May skip webfont if not cached—great for performance |
| `block`        | Short block period, then swap                        |
| `fallback`     | Short block, short swap window                       |

### Generic families [#generic-families]

`serif`, `sans-serif`, `monospace`, `cursive`, `fantasy`, `system-ui`, `ui-sans-serif`, `ui-serif`, `ui-monospace`, `ui-rounded`, `emoji`, `math`, `fangsong`.

## 💡 Examples [#-examples]

### System stack [#system-stack]

```css
:root {
  --font-sans: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, monospace;
}

body {
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.5;
}
```

### Fluid type scale [#fluid-type-scale]

```css
h1 {
  font-size: clamp(1.75rem, 1.2rem + 2vw, 3rem);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.02em;
}
```

### Variable font weight on hover [#variable-font-weight-on-hover]

```css
.nav-link {
  font-family: "InterVar", system-ui, sans-serif;
  font-weight: 500;
  transition: font-weight 120ms ease;
}

.nav-link:hover {
  font-weight: 700;
}
```

### Tabular numbers for data [#tabular-numbers-for-data]

```css
.numeric {
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum" 1;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Listing a webfont without a robust system fallback causes FOUT/FOIT layout jumps—match metrics or reserve space.
* Using `px` everywhere prevents user font-size preferences; prefer `rem` for UI text.
* Applying unitful `line-height` on parents so children inherit unexpected computed values—prefer unitless.
* Loading every weight/style file instead of one variable font increases bytes and requests.
* Setting `font-display: block` on body text, which can leave content invisible too long.

## 🔗 Related [#-related]

* [Text](/docs/css/text)
* [Icons](/docs/css/icon)
* [Buttons](/docs/css/button)
* [Adaptive design](/docs/css/adaptive)


---

# Getting Started with CSS (/docs/css/getting-started)



# Getting Started with CSS [#getting-started-with-css]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

CSS (Cascading Style Sheets) controls how HTML looks: colors, spacing, layout, and responsive behavior. You select elements and declare properties inside rules.

## 🔧 Core concepts [#-core-concepts]

| Idea       | Meaning                               |
| ---------- | ------------------------------------- |
| Rule       | `selector \{ property: value; \}`     |
| Selector   | Which elements the rule targets       |
| Property   | What to change (`color`, `margin`, …) |
| Cascade    | How conflicting rules are resolved    |
| Stylesheet | A `.css` file or `<style>` block      |

Link CSS from HTML with `<link rel="stylesheet" href="styles.css" />`.

## 💡 Examples [#-examples]

**Inline link in HTML:**

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>CSS demo</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <h1 class="title">Hello, CSS</h1>
  </body>
</html>
```

**`styles.css`:**

```css
body {
  font-family: system-ui, sans-serif;
  margin: 2rem;
  background: #f6f7f9;
}

.title {
  color: #0f172a;
  font-size: 2rem;
}
```

**Quick experiment in a `<style>` tag:**

```html
<style>
  p {
    line-height: 1.5;
  }
</style>
```

## ⚠️ Pitfalls [#️-pitfalls]

* Typos in property names fail silently (nothing happens).
* Specificity wars — prefer simple class selectors while learning.
* Browser default styles differ; a small reset/normalize helps later.
* Inline `style=""` attributes override stylesheets and are hard to maintain.

## 🔗 Related [#-related]

* [hello\_world.md](/docs/css/hello-world)
* [selectors\_basics.md](/docs/css/selectors-basics)
* [cascade\_basics.md](/docs/css/cascade-basics)
* [box\_model\_basics.md](/docs/css/box-model-basics)


---

# Glossary (/docs/css/glossary)



# Glossary [#glossary]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Alphabetical glossary of core CSS terms for the cascade, box model, layout, selectors, and modern styling features.

## 🔧 Core concepts [#-core-concepts]

| Term             | Definition                                                                              |
| ---------------- | --------------------------------------------------------------------------------------- |
| At-rule          | A CSS statement starting with `@`, such as `@media` or `@keyframes`.                    |
| Box model        | The content, padding, border, and margin layers that size an element.                   |
| Cascade          | The algorithm that resolves conflicting declarations by origin, layer, and specificity. |
| Containing block | The ancestor box used as the reference for positioned layout.                           |
| Container query  | A rule that styles an element based on its container’s size, not the viewport.          |
| Declaration      | A property–value pair inside a rule, such as `color: red`.                              |
| Em               | A length relative to the element’s own computed font size.                              |
| Flexbox          | A one-dimensional layout model for aligning items in a row or column.                   |
| Grid             | A two-dimensional layout model of rows and columns.                                     |
| Inheritance      | Passing certain computed values from parent to child elements.                          |
| Keyframes        | Named animation frames defined with `@keyframes`.                                       |
| Logical property | Direction-relative properties like `margin-inline` instead of left/right.               |
| Media query      | A condition that applies styles based on device or viewport features.                   |
| Pseudo-class     | A selector state such as `:hover`, `:focus`, or `:nth-child`.                           |
| Pseudo-element   | A selector for generated parts such as `::before` or `::after`.                         |
| Rem              | A length relative to the root element’s font size.                                      |
| Rule set         | A selector plus its block of declarations.                                              |
| Selector         | The pattern that matches which elements a rule applies to.                              |
| Specificity      | A weight used to decide which competing selector wins.                                  |
| Stacking context | A local layering scope that controls how `z-index` paints.                              |
| Shorthand        | A property that sets multiple related longhands at once, like `margin`.                 |
| Transform        | A visual change such as translate, rotate, scale, or skew.                              |
| Transition       | Smooth interpolation of property changes over time.                                     |
| Variable         | A custom property declared with `--name` and read via `var()`.                          |
| Viewport         | The visible area of the page used by units like `vw` and `vh`.                          |
| Z-index          | A stacking order value within a stacking context.                                       |

## 💡 Examples [#-examples]

**Flexbox and variables:**

```css
:root {
  --gap: 1rem;
}
.row {
  display: flex;
  gap: var(--gap);
  align-items: center;
}
```

**Grid and media query:**

```css
.layout {
  display: grid;
  grid-template-columns: 1fr;
}
@media (min-width: 768px) {
  .layout {
    grid-template-columns: 240px 1fr;
  }
}
```

**Specificity and cascade layers:**

```css
@layer base, components;
@layer base {
  button { padding: 0.5rem; }
}
@layer components {
  .btn { padding: 1rem; }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Confusing **margin** (outside border) with **padding** (inside border).
* Mixing **flex** and **grid** goals — one axis vs two axes.
* Treating **pseudo-class** (`:hover`) like a **pseudo-element** (`::before`).
* Assuming higher **z-index** always wins — stacking contexts can trap layers.
* Equating **em** and **rem** — em is relative to the element; rem to the root.

## 🔗 Related [#-related]

* [box\_model](/docs/css/box-model)
* [flex](/docs/css/flex)
* [grid](/docs/css/grid)
* [specificity](/docs/css/specificity)
* [variables](/docs/css/variables)
* [media\_queries](/docs/css/media-queries)


---

# Gradients (/docs/css/gradient)



# Gradients [#gradients]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Gradients are images generated by CSS—usable anywhere `background-image` or `mask-image` accepts an image. The main types are linear, radial, conic, and their repeating variants. Use gradients for soft backgrounds, scrims over photos, progress fills, and decorative accents without exporting bitmap assets.

Modern color stops work well in `oklch` / `oklab` for perceptually even blends; `color-mix()` helps derive stop colors from tokens.

## 🔧 Core concepts [#-core-concepts]

### Gradient functions [#gradient-functions]

| Function                      | Shape                             |
| ----------------------------- | --------------------------------- |
| `linear-gradient()`           | Straight-line blend               |
| `radial-gradient()`           | From center (or position) outward |
| `conic-gradient()`            | Around a center (angles)          |
| `repeating-linear-gradient()` | Tiled linear pattern              |
| `repeating-radial-gradient()` | Tiled radial pattern              |
| `repeating-conic-gradient()`  | Tiled angular pattern             |

### Linear syntax [#linear-syntax]

```css
linear-gradient(
  [ to <side-or-corner> | <angle> ],
  <color-stop-list>
)
```

Examples: `to bottom`, `to top right`, `135deg`. Color stops: `color`, optional position (`30%`, `4rem`).

### Radial & conic [#radial--conic]

| Type   | Key options                                                                               |
| ------ | ----------------------------------------------------------------------------------------- |
| Radial | `circle` \| `ellipse`, size keywords (`closest-side`, `farthest-corner`), `at <position>` |
| Conic  | `from <angle>`, `at <position>`, stops by angle (`0deg`, `25%`)                           |

### Multiple layers [#multiple-layers]

Gradients stack like any background images—list them first for overlays, solid color last as fallback.

## 💡 Examples [#-examples]

### Soft page wash [#soft-page-wash]

```css
body {
  background-color: oklch(0.98 0.01 100);
  background-image: linear-gradient(
    160deg,
    oklch(0.95 0.03 250),
    oklch(0.98 0.01 100) 45%,
    oklch(0.96 0.03 40)
  );
  background-attachment: fixed;
}
```

### Image scrim [#image-scrim]

```css
.hero {
  background:
    linear-gradient(to top, rgb(0 0 0 / 0.75), transparent 55%),
    url("/hero.jpg") center / cover no-repeat;
}
```

### Conic chart / progress ring base [#conic-chart--progress-ring-base]

```css
.pie {
  inline-size: 8rem;
  block-size: 8rem;
  border-radius: 50%;
  background: conic-gradient(
    oklch(0.6 0.18 250) 0 72%,
    oklch(0.9 0.02 250) 0
  );
}
```

### Striped repeating pattern [#striped-repeating-pattern]

```css
.stripes {
  background-image: repeating-linear-gradient(
    -45deg,
    transparent,
    transparent 6px,
    rgb(0 0 0 / 0.06) 6px,
    rgb(0 0 0 / 0.06) 12px
  );
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Hard-coding `left`/`right` in gradients for i18n UIs—prefer `to inline-end` where supported, or logical design tokens.
* Using too many stops in sRGB that band or look muddy—try `oklch` stops for smoother ramps.
* Forgetting a solid `background-color` underneath for print, email, or failed paint.
* Animating gradient stop positions poorly (often not interpolatable)—animate `opacity` / overlays instead.
* Applying huge fixed gradients on `body` with `background-attachment: fixed` on low-end mobile GPUs.

## 🔗 Related [#-related]

* [Background](/docs/css/background)
* [Effects](/docs/css/effects)
* [Images](/docs/css/image)
* [Buttons](/docs/css/button)


---

# CSS Grid (/docs/css/grid)



# CSS Grid [#css-grid]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

CSS Grid is a two-dimensional layout system for rows and columns. Define tracks on a container with `grid-template-*`, place items with line-based or area-based positioning, and control gaps and alignment. Use Grid for page shells, card galleries, dashboards, and any UI where rows and columns interact. Prefer Flexbox for simple one-axis distribution inside a grid cell.

Subgrid (`grid-template-*: subgrid`) lets nested grids inherit parent tracks for aligned columns across components.

## 🔧 Core concepts [#-core-concepts]

### Container properties [#container-properties]

| Property                            | Role                                                 |
| ----------------------------------- | ---------------------------------------------------- |
| `display: grid` \| `inline-grid`    | Establish grid formatting context                    |
| `grid-template-columns` / `rows`    | Track list (`fr`, `px`, `%`, `minmax()`, `repeat()`) |
| `grid-template-areas`               | Named rectangular areas                              |
| `grid-auto-columns` / `rows`        | Implicit track sizing                                |
| `grid-auto-flow`                    | `row` \| `column` \| `dense`                         |
| `gap` / `row-gap` / `column-gap`    | Gutters                                              |
| `justify-items` / `align-items`     | Default cell alignment                               |
| `justify-content` / `align-content` | Tracks inside the container                          |
| `place-items` / `place-content`     | Shorthands                                           |

### Item properties [#item-properties]

| Property                      | Role                                 |
| ----------------------------- | ------------------------------------ |
| `grid-column` / `grid-row`    | Line start / end (`1 / 3`, `span 2`) |
| `grid-area`                   | Area name or four-line shorthand     |
| `justify-self` / `align-self` | Per-item alignment                   |
| `order`                       | Visual order (use carefully)         |

### Track sizing functions [#track-sizing-functions]

| Function                                             | Use                            |
| ---------------------------------------------------- | ------------------------------ |
| `fr`                                                 | Share free space               |
| `minmax(min, max)`                                   | Flexible bounds                |
| `repeat(n, …)` / `repeat(auto-fit, …)` / `auto-fill` | Patterns                       |
| `fit-content()`                                      | Clamp to content up to a limit |
| `min-content` / `max-content` / `auto`               | Content-based tracks           |

## 💡 Examples [#-examples]

### Responsive card gallery [#responsive-card-gallery]

```css
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: 1rem;
}
```

### Holy grail with areas [#holy-grail-with-areas]

```css
.page {
  display: grid;
  grid-template-columns: 12rem 1fr 12rem;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header header"
    "nav    main   aside"
    "footer footer footer";
  min-block-size: 100dvh;
  gap: 1rem;
}

.header { grid-area: header; }
.nav    { grid-area: nav; }
.main   { grid-area: main; }
.aside  { grid-area: aside; }
.footer { grid-area: footer; }

@media (max-width: 48rem) {
  .page {
    grid-template-columns: 1fr;
    grid-template-areas:
      "header"
      "nav"
      "main"
      "aside"
      "footer";
  }
}
```

### Span and dense packing [#span-and-dense-packing]

```css
.board {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-flow: dense;
  gap: 0.5rem;
}

.board .wide {
  grid-column: span 2;
}
```

### Align within cells [#align-within-cells]

```css
.cell-center {
  display: grid;
  place-items: center;
  min-block-size: 10rem;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Using only fixed `px` columns that overflow small viewports—prefer `minmax` + `auto-fit`/`fr`.
* Confusing `auto-fit` (collapses empty tracks) with `auto-fill` (keeps empty tracks).
* Forgetting that percentage row heights need a definite container block size.
* Over-nesting grids when one template + areas would suffice.
* Relying on `order` or visual placement that diverges from DOM order for keyboard users.

## 🔗 Related [#-related]

* [Flexbox](/docs/css/flex)
* [Adaptive design](/docs/css/adaptive)
* [Positioning](/docs/css/position)
* [Multi-column layout](/docs/css/column)


---

# :has() Selector (/docs/css/has-selector)



# :has() Selector [#has-selector]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`:has()` is a relational pseudo-class: select a parent (or earlier sibling context) based on descendants/siblings matching a selector. Enables “parent of” styling long missing from CSS — form validation UI, cards with images, and conditional layouts without JS.

## 🔧 Core concepts [#-core-concepts]

* **Form**: `parent:has(child-selector)`.
* **Relative selectors**: `:has(> img)`, `:has(+ .error)`, `:has(.icon)`.
* **Specificity**: contributes the most specific selector in its argument list.
* **Forgiving vs not**: invalid selectors inside may drop the whole `:has` in some cases — keep args valid.
* **Performance**: powerful; avoid extremely broad `:has(*)` on huge documents.
* **Use with `:is`/`:not`**: `label:not(:has(:checked))`.

```css
.card:has(img) {
  display: grid;
  grid-template-columns: 8rem 1fr;
}
label:has(:invalid) {
  color: crimson;
}
```

## 💡 Examples [#-examples]

```css
/* Field error when control invalid */
.field:has(:user-invalid) {
  border-color: crimson;
}
.field:has(:user-invalid) .hint {
  display: block;
}

/* Nav current section style via fragment targets — example */
section:has(:target) {
  outline: 1px solid var(--accent);
}

/* Empty-ish cards */
.card:not(:has(.body:not(:empty))) {
  opacity: 0.7;
}

/* Sibling previous — style label when input focused */
.field:has(:focus-visible) > .label {
  color: var(--accent);
}

/* Grid: featured when contains badge */
.item:has(.badge-featured) {
  grid-column: span 2;
}

/* Checkbox tree */
.tree li:has(> ul) > .twisty::before {
  content: "▾";
}
```

```css
/* Media layout */
article:has(> figure) {
  max-width: 70rem;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Not a substitute for accessibility — still need proper structure/ARIA.
* Can be costly if used everywhere with deep descendant selectors — scope tightly.
* Specificity surprises when arguments include IDs.
* Older browsers lack `:has` — provide acceptable non-`:has` fallbacks.
* `:has` does not “look up” forever without a subject — the subject is the element before `:has`.

## 🔗 Related [#-related]

* [selectors.md](/docs/css/selectors) — selector overview
* [pseudo\_classes.md](/docs/css/pseudo-classes) — other states
* [specificity.md](/docs/css/specificity) — scoring
* [nesting.md](/docs/css/nesting) — nested :has
* [forms via CSS](/docs/css/pseudo-classes) — :user-invalid


---

# Hello World (/docs/css/hello-world)



# Hello World [#hello-world]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

CSS Hello World usually means styling a heading or page background so you can see a visible change. If the look updates when you refresh, your stylesheet is connected correctly.

## 🔧 Core concepts [#-core-concepts]

| Piece             | Role                             |
| ----------------- | -------------------------------- |
| Selector          | Targets `h1`, `.class`, `#id`, … |
| Declaration       | `property: value;`               |
| Declaration block | `\{ ... \}`                      |
| External CSS      | Best default for learning        |

Change one obvious property first (color or background) to verify the link.

## 💡 Examples [#-examples]

**HTML + CSS pair:**

```html
<!-- index.html -->
<h1>Hello, World!</h1>
```

```css
/* styles.css */
h1 {
  color: darkslateblue;
  text-align: center;
}
```

**Background and body text:**

```css
body {
  background-color: #fff7ed;
  color: #1c1917;
  font-family: Georgia, serif;
}
```

**Class-based hello:**

```html
<p class="hello">Hello, World!</p>
```

```css
.hello {
  font-size: 1.5rem;
  letter-spacing: 0.02em;
}
```

**DevTools tip:** right-click the element → Inspect → watch which rules apply.

## ⚠️ Pitfalls [#️-pitfalls]

* Wrong path in `<link href="...">` means no styles — check the Network tab.
* Caching can hide changes — hard refresh if needed.
* `colour` is invalid; use `color` (American spelling in CSS).
* Styling `html` vs `body` height differently can confuse full-page backgrounds.

## 🔗 Related [#-related]

* [getting\_started.md](/docs/css/getting-started)
* [selectors\_basics.md](/docs/css/selectors-basics)
* [cascade\_basics.md](/docs/css/cascade-basics)
* [box\_model\_basics.md](/docs/css/box-model-basics)


---

# Hover (/docs/css/hover)



# Hover [#hover]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Hover styles respond when a pointing device is over an element (`:hover`). They provide previews, affordance, and progressive disclosure—but they are unreliable on touchscreens and unavailable to keyboard-only users unless mirrored with `:focus-visible` / `:focus-within`. Use hover for enhancement, not for the only path to critical UI.

Feature-query with `@media (hover: hover)` when hover-only behavior would confuse touch users.

## 🔧 Core concepts [#-core-concepts]

### Selectors & companions [#selectors--companions]

| Selector                 | Role                                 |
| ------------------------ | ------------------------------------ |
| `:hover`                 | Pointer over element                 |
| `:focus-visible`         | Keyboard-style focus                 |
| `:focus-within`          | Focus inside a parent (menus, cards) |
| `:active`                | Pressed state                        |
| `@media (hover: hover)`  | Primary input can hover              |
| `@media (pointer: fine)` | Precise pointer (mouse)              |

### Typical properties to change [#typical-properties-to-change]

| Category  | Examples                                    |
| --------- | ------------------------------------------- |
| Color     | `color`, `background-color`, `border-color` |
| Elevation | `box-shadow`, `translate`                   |
| Emphasis  | `opacity`, `filter`, `text-decoration`      |
| Motion    | `transform`, `transition`                   |

Keep transitions short (100–200ms) for UI chrome; longer for decorative motion.

### Safe pattern [#safe-pattern]

```css
.card {
  transition: transform 160ms ease, box-shadow 160ms ease;
}

@media (hover: hover) and (pointer: fine) {
  .card:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 24px rgb(0 0 0 / 0.12);
  }
}

.card:focus-within {
  outline: 2px solid Highlight;
  outline-offset: 2px;
}
```

## 💡 Examples [#-examples]

### Link underline reveal [#link-underline-reveal]

```css
.prose a {
  color: inherit;
  text-decoration-color: transparent;
  text-underline-offset: 0.2em;
  transition: text-decoration-color 150ms ease;
}

.prose a:hover,
.prose a:focus-visible {
  text-decoration-color: currentColor;
}
```

### Icon button feedback [#icon-button-feedback]

```css
.icon-btn {
  background: transparent;
  border-radius: 0.5rem;
  transition: background-color 120ms ease;
}

.icon-btn:hover {
  background: color-mix(in oklab, CanvasText 8%, transparent);
}

.icon-btn:active {
  background: color-mix(in oklab, CanvasText 14%, transparent);
}
```

### Show action affordances on card [#show-action-affordances-on-card]

```css
.card .actions {
  opacity: 0;
  transition: opacity 150ms ease;
}

.card:hover .actions,
.card:focus-within .actions {
  opacity: 1;
}
```

### Disable sticky-hover traps on touch [#disable-sticky-hover-traps-on-touch]

```css
@media (hover: none) {
  .tooltip[data-show-on-hover] {
    display: none;
  }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Hiding essential controls only behind `:hover` so touch and keyboard users never see them.
* Leaving “stuck” hover styles on touch devices after tap—gate with `(hover: hover)`.
* Animating expensive properties (`width`, `top`, large `filter`) on every hover.
* Removing focus outlines and only styling `:hover`, which fails keyboard navigation.
* Nesting hover rules that fight (`parent:hover child` vs `child:hover`) and cause flicker.

## 🔗 Related [#-related]

* [Buttons](/docs/css/button)
* [Cursor](/docs/css/cursor)
* [Animation](/docs/css/animation)
* [Effects](/docs/css/effects)


---

# Icons (/docs/css/icon)



# Icons [#icons]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Icons in CSS-driven UIs are usually inline SVG, icon fonts, or mask/background images. Inline SVG is preferred for accessibility, theming via `currentColor`, and crisp scaling. Style icons to align with text, inherit color, and keep decorative icons hidden from assistive tech with `aria-hidden="true"`.

Treat icon size as a design token (`1em` or fixed rem) so icons scale with surrounding type when appropriate.

## 🔧 Core concepts [#-core-concepts]

### Delivery techniques [#delivery-techniques]

| Technique               | Pros                                  | Cons                         |
| ----------------------- | ------------------------------------- | ---------------------------- |
| Inline SVG              | Colorable, accessible, CSS-targetable | Markup weight if not sprited |
| `<img src="*.svg">`     | Simple caching                        | Harder to recolor            |
| CSS `mask-image`        | Recolor with `background-color`       | Needs careful sizing         |
| Icon font               | Easy swap                             | Ligature/a11y pitfalls, FOIT |
| Sprite / symbol `<use>` | Deduplicates paths                    | Cross-origin/`use` quirks    |

### Alignment & sizing [#alignment--sizing]

| Property / tip                     | Why                        |
| ---------------------------------- | -------------------------- |
| `inline-size` / `block-size`       | Explicit box               |
| `flex-shrink: 0`                   | Prevent crush in flex rows |
| `vertical-align: -0.125em`         | Optical align with text    |
| `display: block` on SVG in buttons | Remove baseline gap        |

### Theming with currentColor [#theming-with-currentcolor]

```css
.icon {
  inline-size: 1.25rem;
  block-size: 1.25rem;
  fill: currentColor; /* or stroke for outline icons */
}
```

Parent `color` then drives the icon.

## 💡 Examples [#-examples]

### Button with inline SVG [#button-with-inline-svg]

```html
<button type="button" class="btn">
  <svg class="icon" aria-hidden="true" focusable="false" viewBox="0 0 24 24">
    <path d="…" />
  </svg>
  Download
</button>
```

```css
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.icon {
  inline-size: 1.125rem;
  block-size: 1.125rem;
  fill: currentColor;
  flex-shrink: 0;
}
```

### Mask-based icon [#mask-based-icon]

```css
.icon-mask {
  display: inline-block;
  inline-size: 1.25rem;
  block-size: 1.25rem;
  background-color: currentColor;
  mask: url("/icons/check.svg") center / contain no-repeat;
  -webkit-mask: url("/icons/check.svg") center / contain no-repeat;
}
```

### Optical alignment in text [#optical-alignment-in-text]

```css
.with-icon {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
}

.with-icon .icon {
  inline-size: 1em;
  block-size: 1em;
}
```

### Standalone icon button (accessible name) [#standalone-icon-button-accessible-name]

```html
<button type="button" class="icon-btn" aria-label="Close">
  <svg class="icon" aria-hidden="true" focusable="false">…</svg>
</button>
```

```css
.icon-btn {
  display: inline-grid;
  place-items: center;
  inline-size: 2.5rem;
  block-size: 2.5rem;
  padding: 0;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Using icon fonts with ligature text that screen readers announce as random letters—prefer SVG + accessible names.
* Leaving SVG focusable in some browsers without `focusable="false"` inside buttons.
* Scaling icons with only `font-size` on icon fonts while stroke widths look uneven—prefer SVG.
* Crushing icons in flex layouts without `flex-shrink: 0`.
* Decorative icons without `aria-hidden` that add noise to the accessibility tree.

## 🔗 Related [#-related]

* [Buttons](/docs/css/button)
* [Images](/docs/css/image)
* [Fonts](/docs/css/font)
* [Flexbox](/docs/css/flex)


---

# Images (/docs/css/image)



# Images [#images]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

CSS for images covers how replaced elements (`<img>`, `<picture>`, `object-fit` containers, and background images) size, crop, and align. Content images belong in HTML (`<img>` / `<picture>`) for semantics, alt text, and lazy loading; CSS then controls layout fit. Use `object-fit` and `object-position` for consistent crops in fixed frames, and modern formats (`avif`, `webp`) via `<picture>` or `image-set()`.

Always reserve space (width/height attributes or aspect-ratio) to reduce layout shift.

## 🔧 Core concepts [#-core-concepts]

### Sizing & fitting [#sizing--fitting]

| Property                | Role                                                     |
| ----------------------- | -------------------------------------------------------- |
| `max-inline-size: 100%` | Prevent overflow in fluid layouts                        |
| `block-size: auto`      | Preserve intrinsic ratio with width                      |
| `aspect-ratio`          | Explicit box ratio before load                           |
| `object-fit`            | `fill` \| `contain` \| `cover` \| `none` \| `scale-down` |
| `object-position`       | Crop anchor (`center`, `top`, percentages)               |
| `image-rendering`       | `auto` \| `crisp-edges` \| `pixelated`                   |

### Responsive sources (HTML + CSS) [#responsive-sources-html--css]

| Tool                     | Use                          |
| ------------------------ | ---------------------------- |
| `srcset` + `sizes`       | Resolution / width switching |
| `<picture>` + `<source>` | Art direction / format       |
| `image-set()`            | CSS background candidates    |

### Decorative vs content [#decorative-vs-content]

| Kind       | Approach                                                            |
| ---------- | ------------------------------------------------------------------- |
| Content    | `<img alt="…">`                                                     |
| Decorative | Empty `alt` or CSS background; don’t rely on background for meaning |

## 💡 Examples [#-examples]

### Fluid content image [#fluid-content-image]

```css
.content img {
  max-inline-size: 100%;
  block-size: auto;
  border-radius: 0.5rem;
}
```

### Cover crop in a fixed frame [#cover-crop-in-a-fixed-frame]

```css
.avatar {
  inline-size: 3rem;
  block-size: 3rem;
  border-radius: 50%;
  overflow: hidden;
}

.avatar img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  object-position: center;
}
```

### Aspect-ratio placeholder [#aspect-ratio-placeholder]

```css
.media-frame {
  aspect-ratio: 16 / 9;
  background: color-mix(in oklab, CanvasText 6%, Canvas);
}

.media-frame > img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}
```

### Picture art direction (markup) [#picture-art-direction-markup]

```html
<picture>
  <source media="(min-width: 64rem)" srcset="/hero-wide.avif" type="image/avif" />
  <source media="(min-width: 64rem)" srcset="/hero-wide.webp" type="image/webp" />
  <img src="/hero-square.jpg" width="800" height="800" alt="Product on a desk" />
</picture>
```

## ⚠️ Pitfalls [#️-pitfalls]

* Omitting width/height or `aspect-ratio`, causing Cumulative Layout Shift as images load.
* Using `background-image` for meaningful pictures—no alt text, harder to print/save.
* Applying `object-fit: cover` without controlling `object-position`, cropping faces badly.
* Setting only `width: 100%` with a fixed height and default `object-fit: fill`, which distorts.
* Serving huge desktop assets to mobile without `srcset`/`sizes` or compressed formats.

## 🔗 Related [#-related]

* [Background](/docs/css/background)
* [Icons](/docs/css/icon)
* [Scale](/docs/css/scale)
* [Effects](/docs/css/effects)


---

# Logical Properties (/docs/css/logical-properties)



# Logical Properties [#logical-properties]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Logical properties use **flow-relative** directions (`inline`/`block`, `start`/`end`) instead of physical `left`/`right`/`top`/`bottom`. They adapt automatically to writing modes and direction (`ltr`/`rtl`, vertical text). Prefer them for margins, padding, borders, and positioning in global UIs.

## 🔧 Core concepts [#-core-concepts]

| Physical             | Logical                                     |
| -------------------- | ------------------------------------------- |
| `width` / `height`   | `inline-size` / `block-size`                |
| `min-width`          | `min-inline-size`                           |
| `margin-left/right`  | `margin-inline-start/end` / `margin-inline` |
| `padding-top/bottom` | `padding-block`                             |
| `border-left`        | `border-inline-start`                       |
| `left` / `right`     | `inset-inline-start/end`                    |
| `text-align: left`   | `text-align: start`                         |

* **Inline axis**: text flow direction; **block axis**: stacking of lines/paragraphs.
* **Shorthands**: `margin-inline`, `padding-block`, `inset: block-start inline-end …`, `border-inline`.
* **Writing mode**: `writing-mode`, `direction`, `unicode-bidi`.

```css
.card {
  margin-inline: auto;
  padding-block: 1rem;
  padding-inline: 1.25rem;
  border-inline-start: 4px solid var(--accent);
  max-inline-size: 60ch;
}
```

## 💡 Examples [#-examples]

```css
/* Absolute pin */
.badge {
  position: absolute;
  inset-block-start: 0.5rem;
  inset-inline-end: 0.5rem;
}

/* RTL-friendly nav */
.nav {
  display: flex;
  gap: 1rem;
  padding-inline: 1rem;
}
.nav .icon {
  margin-inline-end: 0.5rem;
}

/* Logical borders radius (modern) */
.panel {
  border-start-start-radius: 8px;
  border-start-end-radius: 8px;
}

/* Scroll padding */
.scroller {
  scroll-padding-block-start: 4rem;
}
```

```css
/* Mixed: physical still OK for shadows/art direction */
.hero {
  background-position: right top; /* intentional art */
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Mixing physical and logical on the same edge is confusing — pick one system per component.
* Older browsers may lack some logical radius/inset properties — check targets.
* `left` in animations/tooling may not map 1:1 when converting — test RTL.
* Transforms like `translateX` are still physical — use logical translations carefully (`translate: auto` evolving).
* Third-party CSS often physical — isolate overrides.

## 🔗 Related [#-related]

* [box\_model.md](/docs/css/box-model) — box edges
* [position.md](/docs/css/position) — inset
* [text.md](/docs/css/text) — alignment
* [flex.md](/docs/css/flex) — start/end alignment
* [adaptive.md](/docs/css/adaptive) — i18n layouts


---

# Media Queries (/docs/css/media-queries)



# Media Queries [#media-queries]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`@media` applies styles based on device/viewport characteristics: width, hover capability, color scheme, resolution, and more. Use them for layout breakpoints and accessibility preferences. Prefer mobile-first `min-width` queries and modern ranges.

## 🔧 Core concepts [#-core-concepts]

* **Syntax**: `@media (condition) \{ ... \}` / `@media screen and (...)`.
* **Width**: `(min-width: 48rem)`, range `(width >= 48rem)`, `(48rem &lt;= width &lt;= 80rem)`.
* **Preferences**: `prefers-color-scheme`, `prefers-reduced-motion`, `prefers-contrast`.
* **Pointer/hover**: `(hover: hover)`, `(pointer: fine|coarse)`.
* **Display**: `print`, `screen`, `(display-mode: standalone)`.
* **Script**: `matchMedia` mirrors the same queries in JS.

```css
.card {
  display: grid;
  gap: 1rem;
}
@media (min-width: 40rem) {
  .card {
    grid-template-columns: 1fr 1fr;
  }
}
@media (prefers-reduced-motion: reduce) {
  * {
    animation: none !important;
    transition: none !important;
  }
}
```

## 💡 Examples [#-examples]

```css
/* Mobile first */
.nav {
  flex-direction: column;
}
@media (width >= 64rem) {
  .nav {
    flex-direction: row;
  }
}

/* Range */
@media (30rem <= width <= 60rem) {
  .side {
    display: none;
  }
}

/* Interaction */
@media (hover: hover) and (pointer: fine) {
  .tile:hover {
    transform: translateY(-2px);
  }
}

/* Dark */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #111;
  }
}

/* High DPI assets often via picture/srcset; CSS: */
@media (resolution >= 2dppx) {
  .icon {
    background-size: 50%;
  }
}

/* Container queries for components — see container_queries.md */
```

```css
/* Avoid too many breakpoints — design fluidly first */
```

## ⚠️ Pitfalls [#️-pitfalls]

* Desktop-first `max-width` stacks get messy — prefer `min-width` progression.
* `em`/`rem` in queries refer to initial font size, not element-local rem in some engines — know your units.
* Hover styles on touch devices can stick — gate with `(hover: hover)`.
* Don’t hide critical content only on “mobile” queries — responsive ≠ removed.
* Overlapping conflicting breakpoints cause hard-to-trace bugs — keep a scale.

## 🔗 Related [#-related]

* [container\_queries.md](/docs/css/container-queries) — component queries
* [dark\_mode.md](/docs/css/dark-mode) — color scheme
* [print.md](/docs/css/print) — print media
* [adaptive.md](/docs/css/adaptive) — responsive patterns
* [../Javascript/DOM/media\_query\_list.md](/docs/css/../javascript/dom/media-query-list) — JS API


---

# Nesting (/docs/css/nesting)



# Nesting [#nesting]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Native CSS nesting lets you write nested rules and at-rules like Sass, without a preprocessor. Use `&` for the parent selector. Keep nesting shallow for readability and specificity control.

## 🔧 Core concepts [#-core-concepts]

* **Nested style rule**: a rule inside another; must usually start with `&` or a nesting selector when ambiguous.
* **`&`**: parent reference — `.card \{ &:hover \{\} \}` → `.card:hover`.
* **Combinators**: `& > .child`, `& + &`, `& .desc`.
* **At-rules**: nest `@media`, `@supports`, `@layer`, `@container`.
* **Specificity**: nested selectors concatenate — still counts as written.
* **Declarations**: may mix with nested rules; modern parsers allow declarations first or interleaved (browser-dependent historically — prefer declarations then nests).

```css
.card {
  padding: 1rem;
  & h2 {
    margin: 0;
  }
  &:hover {
    box-shadow: 0 4px 12px rgb(0 0 0 / 0.1);
  }
  @media (min-width: 40rem) {
    padding: 1.5rem;
  }
}
```

## 💡 Examples [#-examples]

```css
.nav {
  display: flex;
  & ul {
    display: flex;
    gap: 1rem;
    list-style: none;
  }
  & a {
    color: inherit;
    text-decoration: none;
    &:focus-visible {
      outline: 2px solid var(--accent);
    }
  }
}

/* BEM-ish without repetition */
.btn {
  border: 0;
  &--primary {
    background: var(--accent);
  }
  &__icon {
    margin-inline-end: 0.5rem;
  }
}

/* :is wrapping */
.prose {
  & :is(h1, h2, h3) {
    line-height: 1.2;
  }
}

/* Nested container */
.widget {
  container-type: inline-size;
  @container (min-width: 20rem) {
    & .meta {
      display: flex;
    }
  }
}
```

```css
/* Invalid without & in some cases for starting type selectors — use & */
.card {
  & table {
  } /* good */
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Deep nesting (`& & & &`) recreates specificity hell — limit to 2–3 levels.
* Forgetting `&` can make selectors mean something else or be invalid.
* Output selector list can explode with `:is` — inspect DevTools.
* Mixing preprocessors + native nesting can double-process — pick one pipeline.
* Older browsers need PostCSS nesting plugin — know your baseline.

## 🔗 Related [#-related]

* [selectors.md](/docs/css/selectors) — selector grammar
* [specificity.md](/docs/css/specificity) — weights
* [media\_queries.md](/docs/css/media-queries) — nested media
* [container\_queries.md](/docs/css/container-queries) — nested @container
* [cascade\_layers.md](/docs/css/cascade-layers) — @layer


---

# Object Fit (/docs/css/object-fit)



# Object Fit [#object-fit]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`object-fit` and `object-position` control how replaced content (`img`, `video`, `canvas`) fills its box when the aspect ratios differ. Use with fixed sizes or `aspect-ratio` for consistent media frames without distortion (unless you choose `fill`).

## 🔧 Core concepts [#-core-concepts]

| `object-fit` | Behavior                                |
| ------------ | --------------------------------------- |
| `fill`       | stretch to box (default for some cases) |
| `contain`    | letterbox — entire media visible        |
| `cover`      | crop — fill box, preserve ratio         |
| `none`       | intrinsic size                          |
| `scale-down` | none or contain, whichever is smaller   |

* **`object-position`**: `center`, `top`, `25% 75%`, logical positions evolving.
* Applies to **replaced elements**, not background images (`background-size` instead).

```css
.thumb {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  object-position: center;
}
```

## 💡 Examples [#-examples]

```css
/* Hero video */
.hero video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Logo without crop */
.logo {
  width: 160px;
  height: 64px;
  object-fit: contain;
}

/* Avatar */
.avatar {
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  object-fit: cover;
  object-position: top;
}

/* Prefer cover in cards, contain in galleries of diagrams */
.diagram {
  object-fit: contain;
  background: #f4f4f4;
}

/* Pair with aspect-ratio wrapper */
.frame {
  aspect-ratio: 16 / 9;
}
.frame > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
```

```html
<img src="photo.jpg" alt="" width="800" height="600" />
```

## ⚠️ Pitfalls [#️-pitfalls]

* Without an explicit box size (or both dimensions), `object-fit` has nothing to fit into.
* `fill` distorts — rarely what you want for photos.
* Background images use different properties — don’t confuse with `object-*`.
* Focal point cropping may need `object-position` or art-direction (`<picture>`).
* Accessibility: cropped faces can remove important content — choose position carefully.

## 🔗 Related [#-related]

* [aspect\_ratio.md](/docs/css/aspect-ratio) — ratio boxes
* [image.md](/docs/css/image) — image CSS
* [background.md](/docs/css/background) — background-size
* [../Html/images.md](/docs/css/../html/images) — img element
* [../Html/picture\_source.md](/docs/css/../html/picture-source) — art direction


---

# Overflow (/docs/css/overflow)



# Overflow [#overflow]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`overflow` controls how content that doesn’t fit a box is handled: visible, clipped, or scrollable. Logical longhands and `overflow-wrap` / `text-overflow` handle text. Overflow values other than `visible` often create scroll containers and affect sticky/margin collapse.

## 🔧 Core concepts [#-core-concepts]

| Value     | Behavior                                         |
| --------- | ------------------------------------------------ |
| `visible` | paint outside (default)                          |
| `hidden`  | clip, no scroll UI                               |
| `clip`    | clip without programmatic scroll                 |
| `scroll`  | always show scrollports (axes may still overlay) |
| `auto`    | scrollbars when needed                           |

* **Shorthand**: `overflow: x y` / `overflow: auto`.
* **Axes**: `overflow-x`, `overflow-y`, `overflow-inline`, `overflow-block`.
* **Text**: `text-overflow: ellipsis` needs overflow ≠ visible + nowrap (usually).
* **`overflow-wrap` / `word-break`**: wrapping long strings.
* **Scroll**: `scroll-behavior`, `overscroll-behavior`, scroll snap.

```css
.panel {
  max-height: 240px;
  overflow: auto;
}
.truncate {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
```

## 💡 Examples [#-examples]

```css
/* Prevent body scroll under modal */
body.modal-open {
  overflow: hidden;
}

/* Contain paint */
.media {
  overflow: hidden;
  border-radius: 12px;
}

/* Horizontal scroller */
.scroller {
  display: flex;
  gap: 1rem;
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

/* Long URLs */
.prose a {
  overflow-wrap: anywhere;
}

/* Sticky inside overflow */
.sidebar {
  overflow: auto;
  height: 100%;
}
.sidebar h2 {
  position: sticky;
  top: 0;
}
```

```css
/* overlay scrollbars hint (limited support) */
.scroll {
  overflow: overlay;
} /* deprecated — use auto */
```

## ⚠️ Pitfalls [#️-pitfalls]

* `overflow-x: hidden` + `overflow-y: visible` computes to `auto` in many cases — can’t mix freely.
* Clipping kills `position: sticky` relative to outer viewport if an ancestor scrolls/clips incorrectly.
* `overflow: hidden` is not a security boundary for content.
* Nested scroll areas hurt UX — prefer one primary scroller.
* Ellipsis requires a bounded width — flex items need `min-width: 0`.

## 🔗 Related [#-related]

* [scroll.md](/docs/css/scroll) — scrolling
* [scroll\_snap.md](/docs/css/scroll-snap) — snap
* [sticky.md](/docs/css/sticky) — sticky constraints
* [box\_model.md](/docs/css/box-model) — sizing
* [text.md](/docs/css/text) — wrapping


---

# Positioning (/docs/css/position)



# Positioning [#positioning]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The `position` property controls how an element is placed in the document flow and how `inset` / `top` / `right` / `bottom` / `left` offsets apply. Static and relative stay in flow; absolute and fixed are removed from flow; sticky toggles between relative and fixed within a scroll ancestor. Use positioning for overlays, badges, sticky headers, and escape hatches—not as a substitute for Flexbox or Grid page layout.

Prefer logical insets (`inset-block`, `inset-inline`) for writing-mode-aware UI.

## 🔧 Core concepts [#-core-concepts]

### Position values [#position-values]

| Value      | In flow?          | Containing block (offsets)                                                       |
| ---------- | ----------------- | -------------------------------------------------------------------------------- |
| `static`   | Yes               | Offsets ignored                                                                  |
| `relative` | Yes               | Own normal position                                                              |
| `absolute` | No                | Nearest positioned ancestor (not `static`), else initial containing block        |
| `fixed`    | No                | Viewport (unless an ancestor transforms/filters/etc. creates a containing block) |
| `sticky`   | Yes (until stuck) | Nearest scrollport; needs inset threshold                                        |

### Inset properties [#inset-properties]

| Property                       | Notes                                                  |
| ------------------------------ | ------------------------------------------------------ |
| `top` `right` `bottom` `left`  | Physical edges                                         |
| `inset`                        | Shorthand for four physical insets                     |
| `inset-block` / `inset-inline` | Logical pairs                                          |
| `inset-block-start` etc.       | Logical singles                                        |
| `z-index`                      | Stacking within a stacking context (`auto` or integer) |

### Stacking context triggers (common) [#stacking-context-triggers-common]

`position` + `z-index` other than `auto`, `opacity &lt; 1`, `transform`, `filter`, `isolation`, `fixed`/`sticky` in many engines, and more. Nested contexts can trap `z-index`.

## 💡 Examples [#-examples]

### Badge on a relative parent [#badge-on-a-relative-parent]

```css
.icon-wrap {
  position: relative;
  display: inline-grid;
}

.badge {
  position: absolute;
  inset-block-start: -0.25rem;
  inset-inline-end: -0.25rem;
  min-inline-size: 1rem;
  block-size: 1rem;
  border-radius: 999px;
  background: tomato;
  color: white;
  font-size: 0.65rem;
  place-content: center;
  display: grid;
}
```

### Fixed toast [#fixed-toast]

```css
.toast {
  position: fixed;
  inset-block-end: 1rem;
  inset-inline: 1rem;
  z-index: 1000;
  max-inline-size: min(24rem, 100% - 2rem);
  margin-inline-start: auto; /* push to inline-end when full width allowed */
}
```

### Sticky section header [#sticky-section-header]

```css
.section__title {
  position: sticky;
  inset-block-start: 0;
  background: Canvas;
  padding-block: 0.5rem;
  z-index: 1;
}
```

### Full-bleed absolute overlay [#full-bleed-absolute-overlay]

```css
.modal-root {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background: rgb(0 0 0 / 0.4);
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Using `absolute` for primary layout instead of Grid/Flex, causing fragile overlaps on resize.
* Expecting `fixed` relative to the viewport when a parent has `transform`, `filter`, or `perspective`—it becomes a containing block.
* Sticky failing because an ancestor has `overflow: hidden` / `auto` without enough scroll room.
* Fighting stacking with huge `z-index` values instead of restructuring stacking contexts.
* Offsetting with physical `left`/`right` only, breaking RTL layouts—prefer logical insets.

## 🔗 Related [#-related]

* [Flexbox](/docs/css/flex)
* [CSS Grid](/docs/css/grid)
* [Scroll](/docs/css/scroll)
* [Transforms](/docs/css/transform)


---

# Print Styles (/docs/css/print)



# Print Styles [#print-styles]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Print CSS adapts layouts for paper and PDF via `@media print` and paged properties (`page-break_*` / `break-*`). Hide chrome, expand links, avoid wasted ink, and control breaks inside articles. Test with the browser’s print preview.

## 🔧 Core concepts [#-core-concepts]

* **Query**: `@media print \{ ... \}`.
* **Breaks**: `break-before/after/inside`, legacy `page-break-*`.
* **`@page`**: size, margin — `@page \{ margin: 1.5cm; \}`.
* **Widows/orphans**: `orphans`, `widows` line counts.
* **Colors**: `print-color-adjust: exact` when backgrounds must print.
* **Units**: `cm`, `in`, `pt` useful for paper.

```css
@media print {
  nav,
  .ads,
  .no-print {
    display: none !important;
  }
  a[href]::after {
    content: " (" attr(href) ")";
    font-size: 0.8em;
  }
  body {
    color: #000;
    background: #fff;
  }
}
```

## 💡 Examples [#-examples]

```css
@page {
  size: A4;
  margin: 16mm;
}

@media print {
  .page {
    break-after: page;
  }
  h2,
  h3 {
    break-after: avoid;
  }
  pre,
  table,
  figure {
    break-inside: avoid;
  }
  img {
    max-width: 100% !important;
  }
  .shadow-card {
    box-shadow: none;
    border: 1px solid #ccc;
  }
  a {
    text-decoration: underline;
  }
  /* optional: only external URLs */
  a[href^="http"]::after {
    content: " (" attr(href) ")";
  }
}

/* Screen-only */
@media screen {
  .print-only {
    display: none;
  }
}
```

```css
@media print {
  .brand-bar {
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Fixed/sticky headers often repeat awkwardly — hide or static them for print.
* Dark themes waste ink and reduce contrast on paper — force light print colors.
* `position: fixed` elements can overlay every page — neutralize.
* Very long URLs in `::after` can overflow — consider shortening or omitting internals.
* Flex/grid print support is better than before but still verify complex dashboards.

## 🔗 Related [#-related]

* [media\_queries.md](/docs/css/media-queries) — @media
* [overflow.md](/docs/css/overflow) — clipping
* [background.md](/docs/css/background) — print backgrounds
* [text.md](/docs/css/text) — typography
* [reset\_normalize.md](/docs/css/reset-normalize) — base styles


---

# Pseudo-classes (/docs/css/pseudo-classes)



# Pseudo-classes [#pseudo-classes]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Pseudo-classes select elements in a particular state or structural position (`:hover`, `:focus-visible`, `:nth-child`, `:valid`). They help style interaction and structure without extra markup. Prefer `:focus-visible` for keyboard-friendly outlines.

## 🔧 Core concepts [#-core-concepts]

| Group       | Examples                                                                                                                       |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------ |
| User action | `:hover` `:active` `:focus` `:focus-visible` `:focus-within`                                                                   |
| Location    | `:link` `:visited` `:target`                                                                                                   |
| Input       | `:checked` `:disabled` `:enabled` `:required` `:optional` `:valid` `:invalid` `:user-invalid` `:placeholder-shown` `:autofill` |
| Structural  | `:first-child` `:last-child` `:nth-child()` `:nth-of-type()` `:only-child` `:empty`                                            |
| Logical     | `:is()` `:where()` `:not()` `:has()`                                                                                           |
| Linguistic  | `:lang()` `:dir()`                                                                                                             |

```css
button:hover {
  filter: brightness(1.05);
}
button:focus-visible {
  outline: 2px solid var(--accent);
}
form:focus-within {
  border-color: var(--accent);
}
```

## 💡 Examples [#-examples]

```css
/* Zebra + first */
tr:nth-child(odd) {
  background: #fafafa;
}
li:not(:last-child) {
  margin-bottom: 0.5rem;
}

/* Checkbox UI */
input[type="checkbox"]:checked + .label {
  text-decoration: line-through;
}

/* Valid/invalid after interaction */
input:user-invalid {
  border-color: crimson;
}
input:user-valid {
  border-color: seagreen;
}

/* Empty state */
.list:empty::before {
  content: "Nothing here";
  color: #888;
}

/* Soft :is */
:is(h1, h2, h3):first-child {
  margin-top: 0;
}

/* Modal open on dialog */
dialog:open {
  border-radius: 12px;
}
```

```css
/* Avoid :visited privacy limits — only limited props allowed */
a:visited {
  color: rebeccapurple;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `:hover` on touch devices can “stick” — pair with `@media (hover: hover)`.
* Styling `:invalid` from page load is noisy — use `:user-invalid`.
* `:visited` is privacy-restricted — few properties apply.
* `:empty` is false if whitespace text nodes exist.
* Specificity of most pseudo-classes equals a class (except `:where`).

## 🔗 Related [#-related]

* [pseudo\_elements.md](/docs/css/pseudo-elements) — ::pseudo
* [selectors.md](/docs/css/selectors) — selector overview
* [has\_selector.md](/docs/css/has-selector) — :has
* [hover.md](/docs/css/hover) — hover patterns
* [specificity.md](/docs/css/specificity) — weights


---

# Pseudo-elements (/docs/css/pseudo-elements)



# Pseudo-elements [#pseudo-elements]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Pseudo-elements style or generate fragments of elements: `::before`/`::after` boxes, `::placeholder`, `::selection`, `::marker`, `::first-line`, and `::part` for shadow trees. They are not real DOM nodes — limited for accessibility and JS querying.

## 🔧 Core concepts [#-core-concepts]

| Pseudo-element                    | Role                               |
| --------------------------------- | ---------------------------------- |
| `::before` / `::after`            | generated children; need `content` |
| `::placeholder`                   | input placeholder text             |
| `::selection`                     | highlighted text                   |
| `::marker`                        | list marker                        |
| `::first-letter` / `::first-line` | typographic accents                |
| `::backdrop`                      | dialog/fullscreen backdrop         |
| `::part(name)`                    | style shadow parts from outside    |
| `::file-selector-button`          | file input button                  |

* Double-colon `::` is modern; single `:` still works for legacy ones.
* Generated content is not in the accessibility tree as real text in all cases — don’t put critical info only in `content`.

```css
.external::after {
  content: " ↗";
  font-size: 0.85em;
}
::selection {
  background: #ffe08a;
}
```

## 💡 Examples [#-examples]

```css
/* Icon via mask / content */
.icon-check::before {
  content: "";
  display: inline-block;
  width: 1em;
  height: 1em;
  background: currentColor;
  mask: url(/check.svg) center / contain no-repeat;
}

/* Clearfix-ish */
.row::after {
  content: "";
  display: block;
  clear: both;
}

/* Placeholder */
input::placeholder {
  color: #999;
  opacity: 1;
}

/* Marker */
li::marker {
  color: var(--accent);
  font-weight: 700;
}

/* Dialog */
dialog::backdrop {
  background: rgb(0 0 0 / 0.5);
  backdrop-filter: blur(2px);
}

/* Shadow part */
x-button::part(base) {
  border-radius: 8px;
}
```

```css
/* Quotes */
q::before {
  content: open-quote;
}
q::after {
  content: close-quote;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Without `content`, `::before`/`::after` won’t generate a box (except some browser quirks).
* Can’t attach event listeners to pseudo-elements — use real elements when interaction is needed.
* Screen readers may ignore or mishandle decorative `content` — keep meaningful text in DOM.
* Only one `::before` and one `::after` per element.
* `::first-line` accepts a limited property set.

## 🔗 Related [#-related]

* [pseudo\_classes.md](/docs/css/pseudo-classes) — states
* [selectors.md](/docs/css/selectors) — overview
* [icon.md](/docs/css/icon) — icon techniques
* [effects.md](/docs/css/effects) — decorative effects
* [../Javascript/DOM/shadow\_dom.md](/docs/css/../javascript/dom/shadow-dom) — ::part


---

# Reset & Normalize (/docs/css/reset-normalize)



# Reset & Normalize [#reset--normalize]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Resets and normalize stylesheets reduce browser default inconsistencies. A **reset** aggressively zeros margins/padding; **normalize** preserves useful defaults while fixing bugs. Modern projects often use a small opinionated base (e.g. border-box, margin wipe, media defaults) instead of huge legacy resets.

## 🔧 Core concepts [#-core-concepts]

* **Goals**: predictable box model, typography baseline, media fluidity, form inheritance.
* **`box-sizing: border-box`**: almost universal recommendation.
* **Inheritance**: forms don’t inherit `font` by default — fix it.
* **Lists/quotes**: decide whether to keep bullets or reset.
* **Layers**: put reset in the earliest `@layer`.
* **Don’t**: remove focus outlines without `:focus-visible` replacement.

```css
@layer reset {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }
  * {
    margin: 0;
  }
  html {
    -webkit-text-size-adjust: 100%;
  }
  body {
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
  }
  img,
  picture,
  video,
  canvas,
  svg {
    display: block;
    max-width: 100%;
  }
  input,
  button,
  textarea,
  select {
    font: inherit;
  }
  p,
  h1,
  h2,
  h3,
  h4,
  h5,
  h6 {
    overflow-wrap: break-word;
  }
}
```

## 💡 Examples [#-examples]

```css
/* Focus visible, not none */
:focus {
  outline: none;
}
:focus-visible {
  outline: 2px solid var(--accent, #06c);
  outline-offset: 2px;
}

/* List opt-in */
ul[role="list"],
ol[role="list"] {
  list-style: none;
  padding: 0;
}

/* Button reset */
button {
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
}

/* Table normalize bits */
table {
  border-collapse: collapse;
  border-spacing: 0;
}

/* Reduce motion baseline */
@media (prefers-reduced-motion: reduce) {
  html:focus-within {
    scroll-behavior: auto;
  }
}
```

```css
/* Prefer small modern base over * { all: unset } nukes */
```

## ⚠️ Pitfalls [#️-pitfalls]

* Ultra-aggressive resets fight third-party widgets — scope when embedding.
* Removing list styles without `role="list"` can hurt VoiceOver semantics in some cases.
* Never `outline: none` without a visible `:focus-visible` alternative.
* Duplicate normalize + framework reboot causes conflicts — pick one base.
* Reset ≠ design system — still define tokens/type after.

## 🔗 Related [#-related]

* [cascade\_layers.md](/docs/css/cascade-layers) — reset layer
* [box\_model.md](/docs/css/box-model) — border-box
* [font.md](/docs/css/font) — typography base
* [button.md](/docs/css/button) — button styles
* [pseudo\_classes.md](/docs/css/pseudo-classes) — focus-visible


---

# Scale (/docs/css/scale)



# Scale [#scale]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Scaling changes an element’s visual size without necessarily affecting layout the same way as `width`/`height`. In modern CSS, prefer the independent `scale` property or `transform: scale()` for UI feedback (hover grow, press shrink, zoom previews). Unlike changing box dimensions, transform-based scale typically does not reflow siblings—ideal for micro-interactions.

For true layout scaling (zoom entire UI), consider `zoom` (non-standard but widely used) or rem-based design tokens; know the trade-offs.

## 🔧 Core concepts [#-core-concepts]

### Ways to scale [#ways-to-scale]

| Approach                         | Layout impact                        | Notes                             |
| -------------------------------- | ------------------------------------ | --------------------------------- |
| `scale: <sx> <sy>?`              | Visual; used space usually unchanged | Individual transform property     |
| `transform: scale()`             | Same as above                        | Can combine with rotate/translate |
| `width` / `height` / `font-size` | Reflows                              | Real box change                   |
| `zoom`                           | Affects layout in supporting engines | Not in formal CSS standard        |
| SVG `viewBox` / `width`          | Vector scaling                       | Best for icons/illustrations      |

### Transform origin [#transform-origin]

| Property           | Role                                                    |
| ------------------ | ------------------------------------------------------- |
| `transform-origin` | Pivot for scale/rotate (`center`, `top left`, `%`)      |
| `transform-box`    | `border-box` \| `fill-box` \| `view-box` (SVG-relevant) |

Uniform scale: `scale: 1.05` or `scale(1.05)`. Non-uniform: `scale: 1.2 0.9`.

### Accessibility [#accessibility]

Large unexpected scale animations can bother users—respect `prefers-reduced-motion` and don’t rely on scale alone for meaning.

## 💡 Examples [#-examples]

### Hover grow (compositor-friendly) [#hover-grow-compositor-friendly]

```css
.card {
  transform-origin: center;
  transition: scale 160ms ease;
  scale: 1;
}

@media (hover: hover) {
  .card:hover {
    scale: 1.03;
  }
}

@media (prefers-reduced-motion: reduce) {
  .card { transition: none; }
  .card:hover { scale: 1; }
}
```

### Press feedback on button [#press-feedback-on-button]

```css
.btn:active {
  scale: 0.98;
}
```

### Zoom preview from corner [#zoom-preview-from-corner]

```css
.thumb {
  overflow: hidden;
}

.thumb img {
  transform-origin: center;
  transition: transform 220ms ease;
}

.thumb:hover img {
  transform: scale(1.08);
}
```

### Scale with translate for popover [#scale-with-translate-for-popover]

```css
.popover[data-open="true"] {
  scale: 1;
  opacity: 1;
}

.popover[data-open="false"] {
  scale: 0.96;
  opacity: 0;
  transition: scale 120ms ease, opacity 120ms ease;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Scaling up without `overflow: hidden` on parents so content paints outside and overlaps neighbors.
* Using `scale` for responsive layout instead of fluid type/grid—hit targets and text reflow won’t match the visual size.
* Forgetting `transform-origin`, so elements appear to slide while scaling.
* Combining conflicting `transform` shorthand and individual `scale`/`translate` properties without understanding the combined used transform.
* Animating scale on huge filtered layers, which can be costly on low-end GPUs.

## 🔗 Related [#-related]

* [Transforms](/docs/css/transform)
* [Animation](/docs/css/animation)
* [Hover](/docs/css/hover)
* [Images](/docs/css/image)


---

# Scroll (/docs/css/scroll)



# Scroll [#scroll]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Scroll-related CSS controls overflow, scroll snapping, scrollbars, overscroll behavior, and scroll-driven interactions. Use it to create readable regions, carousels, sticky companions, and safer nested scroll areas. Prefer intentional overflow (`auto` / `hidden`) over accidental clipping, and always ensure keyboard and focusable content remain reachable inside scrollports.

Logical properties (`overflow-inline`, `overflow-block`) help in vertical and horizontal writing modes.

## 🔧 Core concepts [#-core-concepts]

### Overflow [#overflow]

| Property                             | Values / role                                           |
| ------------------------------------ | ------------------------------------------------------- |
| `overflow`                           | `visible` \| `hidden` \| `clip` \| `scroll` \| `auto`   |
| `overflow-x` / `overflow-y`          | Per axis (physical)                                     |
| `overflow-inline` / `overflow-block` | Logical axes                                            |
| `overscroll-behavior`                | `auto` \| `contain` \| `none` — chained scroll / bounce |

### Scroll snap [#scroll-snap]

| Property            | Role                                                  |
| ------------------- | ----------------------------------------------------- |
| `scroll-snap-type`  | `x`/`y`/`both` + `mandatory`/`proximity` on container |
| `scroll-snap-align` | `start` \| `center` \| `end` on items                 |
| `scroll-snap-stop`  | `normal` \| `always`                                  |
| `scroll-padding`    | Insets for snap/scroll targets (sticky headers)       |
| `scroll-margin`     | Outset on targets for `scrollIntoView` / snap         |

### Scrollbars & utilities [#scrollbars--utilities]

| Feature                               | Notes                                        |
| ------------------------------------- | -------------------------------------------- |
| `scrollbar-gutter: stable`            | Reserve space to avoid layout shift          |
| `scrollbar-width` / `scrollbar-color` | Standard scrollbar styling (limited)         |
| `::-webkit-scrollbar*`                | WebKit/Blink custom scrollbars               |
| `scroll-behavior: smooth`             | Animated navigation (respect reduced motion) |

## 💡 Examples [#-examples]

### Scrollable panel [#scrollable-panel]

```css
.panel {
  max-block-size: min(24rem, 70dvh);
  overflow: auto;
  overscroll-behavior: contain;
  scrollbar-gutter: stable;
}
```

### Horizontal snap carousel [#horizontal-snap-carousel]

```css
.carousel {
  display: flex;
  gap: 1rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: 1rem;
  -webkit-overflow-scrolling: touch;
}

.carousel > .slide {
  flex: 0 0 min(80%, 20rem);
  scroll-snap-align: start;
}
```

### Offset for sticky header anchors [#offset-for-sticky-header-anchors]

```css
:root {
  --header-h: 3.5rem;
}

.site-header {
  position: sticky;
  inset-block-start: 0;
  block-size: var(--header-h);
}

:target,
[id] {
  scroll-margin-block-start: calc(var(--header-h) + 0.5rem);
}
```

### Smooth scroll with reduced motion [#smooth-scroll-with-reduced-motion]

```css
html {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Putting `overflow: hidden` on ancestors and breaking `position: sticky` descendants.
* Nested scroll areas that trap scroll chaining—use `overscroll-behavior: contain` thoughtfully.
* `scroll-behavior: smooth` without a reduced-motion fallback.
* Snap carousels that hide focusable controls off-screen without keyboard alternatives.
* Custom WebKit scrollbar CSS that removes affordance or fails contrast checks.

## 🔗 Related [#-related]

* [Positioning](/docs/css/position)
* [Adaptive design](/docs/css/adaptive)
* [Flexbox](/docs/css/flex)
* [Hover](/docs/css/hover)


---

# Scroll Snap (/docs/css/scroll-snap)



# Scroll Snap [#scroll-snap]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

CSS scroll snap aligns a scroll container’s viewport to snap positions on children — carousels, paginated strips, and section snapping — without heavy JS. Configure snap on the container and snap alignment on items.

## 🔧 Core concepts [#-core-concepts]

| Property            | Where     | Values                                   |
| ------------------- | --------- | ---------------------------------------- |
| `scroll-snap-type`  | container | `x`/`y`/`both` + `mandatory`/`proximity` |
| `scroll-snap-align` | items     | `start` `center` `end` `none`            |
| `scroll-snap-stop`  | items     | `normal` `always`                        |
| `scroll-padding`    | container | inset for sticky headers                 |
| `scroll-margin`     | items     | snap area outset                         |

* **Mandatory**: always settle on a snap point; **proximity**: only if close.
* Works with overflow scrollers (`overflow-x: auto`).
* Pair with `scroll-behavior: smooth` carefully (a11y).

```css
.scroller {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  gap: 1rem;
}
.scroller > * {
  flex: 0 0 80%;
  scroll-snap-align: center;
}
```

## 💡 Examples [#-examples]

```css
/* Full-page sections */
html {
  scroll-snap-type: y proximity;
}
section {
  min-height: 100vh;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

/* Padding for fixed header */
.scroller {
  scroll-padding-inline: 1rem;
  scroll-padding-block-start: 4rem;
}

/* Stop skipping cards */
.card {
  scroll-snap-stop: always;
}

/* Vertical story */
.stories {
  height: 100dvh;
  overflow-y: auto;
  scroll-snap-type: y mandatory;
}
.stories > article {
  height: 100dvh;
  scroll-snap-align: start;
}
```

```css
@media (prefers-reduced-motion: reduce) {
  .scroller {
    scroll-snap-type: none;
  }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `mandatory` can trap users on small viewports — test keyboard and screen zoom.
* Nested scrollers with snap fight each other — snap one axis/level.
* Images loading late shift snap positions — reserve sizes (`aspect-ratio`, width/height).
* Snap ≠ carousel accessibility — still provide buttons and focus management.
* iOS/Android quirks with momentum — prefer `proximity` when unsure.

## 🔗 Related [#-related]

* [scroll.md](/docs/css/scroll) — overflow scroll
* [overflow.md](/docs/css/overflow) — scroll containers
* [sticky.md](/docs/css/sticky) — scroll-padding with sticky
* [media\_queries.md](/docs/css/media-queries) — reduced motion
* [flex.md](/docs/css/flex) — horizontal strips


---

# Selectors (/docs/css/selectors)



# Selectors [#selectors]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Selectors target elements for styling. From type/class/id to attributes, combinators, and modern relational selectors (`:is`, `:where`, `:has`). Write selectors that express intent without over-specificity.

## 🔧 Core concepts [#-core-concepts]

| Kind              | Example                                |
| ----------------- | -------------------------------------- |
| Type / class / id | `div` `.card` `#app`                   |
| Attribute         | `[type="text"]` `[data-x]`             |
| Combinators       | `A B` `A > B` `A + B` `A ~ B`          |
| Pseudo-class      | `:hover` `:nth-child` `:focus-visible` |
| Pseudo-element    | `::before` `::placeholder`             |
| Grouping          | `h1, h2` / `:is(h1, h2)`               |
| Relatival         | `:has(> img)`                          |

* **`:where()`*&#x2A;: specificity 0; &#x2A;*`:is()`**: takes most specific argument.
* **Universal**: `*` — use sparingly.
* **Namespace**: `svg|a` rare in HTML docs.

```css
nav > ul > li + li {
  margin-left: 1rem;
}
article:has(img) {
  display: grid;
}
```

## 💡 Examples [#-examples]

```css
/* Attributes */
a[target="_blank"]::after {
  content: "↗";
}
input[type="checkbox"]:checked + label {
  font-weight: 600;
}

/* Structural */
tr:nth-child(even) {
  background: #f6f6f6;
}
li:not(:last-child) {
  border-bottom: 1px solid #ddd;
}

/* Soft specificity */
:where(.prose) a {
  color: var(--link);
}
:is(h1, h2, h3):hover {
  text-decoration: underline;
}

/* Has */
label:has(:invalid) {
  color: crimson;
}
.card:has(> .badge) {
  padding-top: 2rem;
}

/* Focus */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
```

```css
/* Avoid over-qualification */
/* BAD: div.card.panel */
/* GOOD: .card */
```

## ⚠️ Pitfalls [#️-pitfalls]

* IDs (`#x`) crush specificity — prefer classes for UI.
* Descendant selectors (`A B`) are costly when very broad on large DOMs — tighten when needed.
* `:has()` is powerful but can be expensive — avoid pathological deep queries.
* `::before` needs `content` or it won’t generate a box.
* Case sensitivity of attributes depends on language / `i` flag in selectors.

## 🔗 Related [#-related]

* [specificity.md](/docs/css/specificity) — scoring
* [pseudo\_classes.md](/docs/css/pseudo-classes) — states
* [pseudo\_elements.md](/docs/css/pseudo-elements) — generated boxes
* [has\_selector.md](/docs/css/has-selector) — :has deep dive
* [nesting.md](/docs/css/nesting) — nested selectors


---

# Selectors Basics (/docs/css/selectors-basics)



# Selectors Basics [#selectors-basics]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

**Selectors** choose which HTML elements a rule applies to. Start with type, class, and id selectors, then combine them. Keep selectors short and readable.

## 🔧 Core concepts [#-core-concepts]

| Selector   | Example   | Matches                    |
| ---------- | --------- | -------------------------- |
| Type       | `p`       | All `<p>` elements         |
| Class      | `.card`   | `class="card"`             |
| Id         | `#main`   | `id="main"` (one per page) |
| Descendant | `nav a`   | `a` inside `nav`           |
| Child      | `ul > li` | Direct child only          |
| Group      | `h1, h2`  | Both `h1` and `h2`         |
| Universal  | `*`       | Everything (use sparingly) |

Classes are the workhorse of maintainable CSS.

## 💡 Examples [#-examples]

**Type and class:**

```css
h1 {
  font-size: 2rem;
}

.note {
  padding: 1rem;
  background: #eef2ff;
}
```

```html
<h1>Title</h1>
<p class="note">Remember selectors.</p>
```

**Descendant vs child:**

```css
article p {
  margin-bottom: 0.75rem;
}

ul > li {
  list-style: disc;
}
```

**Grouping and multiple classes:**

```css
h1,
h2,
h3 {
  line-height: 1.2;
}

.btn.primary {
  background: #2563eb;
  color: white;
}
```

```html
<button class="btn primary">Save</button>
```

## ⚠️ Pitfalls [#️-pitfalls]

* `#id` is very specific — overuse makes overrides painful.
* `div div div span` selectors are brittle; prefer classes.
* Forgetting the `.` in `.class` styles a non-existent `<class>` element type.
* `ul > li` does not match nested `li` deeper than one level.

## 🔗 Related [#-related]

* [getting\_started.md](/docs/css/getting-started)
* [cascade\_basics.md](/docs/css/cascade-basics)
* [box\_model\_basics.md](/docs/css/box-model-basics)
* [selectors.md](/docs/css/selectors)


---

# Specificity (/docs/css/specificity)



# Specificity [#specificity]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Specificity decides which declaration wins when selectors match the same element. Count IDs, classes/attributes/pseudo-classes, and types/pseudo-elements. Cascade layers, importance, and order also matter — specificity is only one axis.

## 🔧 Core concepts [#-core-concepts]

| Selector piece                | Weight (a,b,c)                                 |
| ----------------------------- | ---------------------------------------------- |
| Inline `style=""`             | wins over selectors (except `!important` wars) |
| `#id`                         | (1,0,0)                                        |
| `.class`, `[attr]`, `:hover`  | (0,1,0)                                        |
| `div`, `::before`             | (0,0,1)                                        |
| `:where()`                    | (0,0,0)                                        |
| `:is()` / `:has()` / `:not()` | specificity of most specific argument          |

* **Tie-break**: later rule in the cascade wins (within same layer/importance).
* **`!important`**: escalates importance; still compare specificity within that bucket.
* **Layers**: `@layer` can make lower-specificity author styles win over unlayered — see cascade layers.

```css
#nav .link {
  /* 1,1,0 */
  color: blue;
}
.link:hover {
  /* 0,2,0 */
  color: red;
} /* loses to #nav .link */
```

## 💡 Examples [#-examples]

```css
/* Soft defaults */
:where(.btn) {
  padding: 0.5rem 1rem;
} /* 0 */
.btn.primary {
  background: var(--accent);
} /* easy override */

/* :is takes max */
:is(#a, .b) span {
  /* 1,0,1 */
}

/* Avoid IDs for styling */
/* BAD */
#header nav ul li a {
}
/* GOOD */
.site-nav a {
}

/* Inline vs class */
/* style="color:red" beats .text { color: blue } */
.text {
  color: blue !important;
} /* beats inline without !important */

/* Attribute vs class — same bucket */
[data-active] {
}
.is-active {
}
```

```css
/* Progressive override */
.card {
  padding: 1rem;
}
.card.compact {
  padding: 0.5rem;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Fighting specificity with ever-longer selectors or `!important` creates unmaintainable CSS.
* IDs in CSS couple to unique DOM nodes — prefer classes.
* `!important` in utilities can be OK; in components it usually signals a specificity problem.
* Shadow DOM has a separate boundary — host/page rules don’t pierce freely.
* Order only matters after layer + importance + specificity compare equal.

## 🔗 Related [#-related]

* [selectors.md](/docs/css/selectors) — selector types
* [cascade\_layers.md](/docs/css/cascade-layers) — @layer
* [pseudo\_classes.md](/docs/css/pseudo-classes) — specificity contributors
* [nesting.md](/docs/css/nesting) — nested specificity
* [variables.md](/docs/css/variables) — theming without specificity wars


---

# Sticky Positioning (/docs/css/sticky)



# Sticky Positioning [#sticky-positioning]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`position: sticky` toggles between relative and fixed positioning within a scroll ancestor based on `top`/`bottom`/`inset-*` thresholds. Ideal for sticky headers, table column labels, and sidebars. Sticky fails when any ancestor has unexpected overflow or insufficient height.

## 🔧 Core concepts [#-core-concepts]

* **Declare**: `position: sticky; top: 0;` (threshold required on the sticking axis).
* **Containing block**: sticks within the nearest scroll ancestor’s padding box.
* **Not fixed to viewport** if an ancestor scrolls/clips first.
* **Stacking**: sticky creates a stacking context when `z-index` is applied.
* **Logical**: `inset-block-start` instead of `top` for writing modes.
* **Tables**: `th \{ position: sticky; top: 0; \}` for header rows.

```css
.header {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--bg);
}
```

## 💡 Examples [#-examples]

```css
/* Subnav under main header */
.subnav {
  position: sticky;
  top: 3.5rem; /* header height */
  z-index: 4;
}

/* Sticky sidebar */
.layout {
  display: grid;
  grid-template-columns: 1fr 16rem;
  gap: 2rem;
  align-items: start;
}
.aside {
  position: sticky;
  top: 1rem;
}

/* Sticky table head */
.table-wrap {
  max-height: 20rem;
  overflow: auto;
}
th {
  position: sticky;
  top: 0;
  background: #fff;
}

/* Both axes rare — stick first column */
td:first-child {
  position: sticky;
  inset-inline-start: 0;
  background: #fff;
}
```

```css
/* Common fix: remove overflow: hidden on parents */
.parent {
  overflow: visible;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Ancestor `overflow: hidden|auto|scroll` often becomes the sticky viewport — or prevents sticking.
* Parent height equals sticky child height → nowhere to travel — parent must be taller.
* Forgetting `top`/`bottom` means it never sticks.
* Transparent sticky headers let content show through — set opaque background.
* `top: 0` under a fixed bar covers content — offset by bar height + `scroll-padding`.

## 🔗 Related [#-related]

* [position.md](/docs/css/position) — position schemes
* [z\_index.md](/docs/css/z-index) — stacking
* [overflow.md](/docs/css/overflow) — ancestor overflow
* [scroll\_snap.md](/docs/css/scroll-snap) — scroll-padding
* [logical\_properties.md](/docs/css/logical-properties) — inset-block-start


---

# Tables (/docs/css/table)



# Tables [#tables]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

CSS table styling covers the table layout model (`display: table*` or real `<table>` markup) plus borders, spacing, and alignment of cells. Use semantic HTML tables for tabular data; use Grid/Flex for non-data layouts that merely look like tables. Modern CSS can make tables responsive with wrappers, `display` switches, or prioritized columns—but accessibility of real tables remains the priority.

Control fixed vs automatic layout with `table-layout`, and borders with `border-collapse`.

## 🔧 Core concepts [#-core-concepts]

### Table-related properties [#table-related-properties]

| Property          | Role                                                                  |
| ----------------- | --------------------------------------------------------------------- |
| `table-layout`    | `auto` (content-based) \| `fixed` (equal/col widths more predictable) |
| `border-collapse` | `separate` \| `collapse`                                              |
| `border-spacing`  | Gap when `separate`                                                   |
| `empty-cells`     | `show` \| `hide`                                                      |
| `caption-side`    | `top` \| `bottom` \| logical variants where supported                 |
| `vertical-align`  | Cell content alignment (`top`, `middle`, `baseline`)                  |

### Display values (for completeness) [#display-values-for-completeness]

`table`, `table-row`, `table-cell`, `table-column`, `table-column-group`, `table-header-group`, `table-footer-group`, `table-row-group`, `inline-table`. Prefer real elements (`<table>`, `<thead>`, `<tbody>`, `<tr>`, `<th>`, `<td>`).

### Styling patterns [#styling-patterns]

| Pattern         | Technique                                                    |
| --------------- | ------------------------------------------------------------ |
| Zebra rows      | `tbody tr:nth-child(even)`                                   |
| Sticky header   | `th \{ position: sticky; top: 0; \}` inside overflow wrapper |
| Numeric columns | `font-variant-numeric: tabular-nums; text-align: end`        |
| Compact density | Reduce cell padding tokens                                   |

## 💡 Examples [#-examples]

### Clean data table [#clean-data-table]

```css
.table {
  inline-size: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
}

.table th,
.table td {
  padding: 0.625rem 0.75rem;
  border-block-end: 1px solid color-mix(in oklab, CanvasText 12%, transparent);
  text-align: start;
}

.table th {
  font-weight: 600;
  background: color-mix(in oklab, CanvasText 4%, Canvas);
}

.table tbody tr:nth-child(even) {
  background: color-mix(in oklab, CanvasText 3%, Canvas);
}

.table .num {
  text-align: end;
  font-variant-numeric: tabular-nums;
}
```

### Fixed layout for predictable columns [#fixed-layout-for-predictable-columns]

```css
.table--fixed {
  table-layout: fixed;
}

.table--fixed th:nth-child(1) { width: 40%; }
.table--fixed th:nth-child(2) { width: 30%; }
.table--fixed th:nth-child(3) { width: 30%; }

.table--fixed td {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
```

### Scroll wrapper with sticky head [#scroll-wrapper-with-sticky-head]

```css
.table-scroll {
  max-block-size: 20rem;
  overflow: auto;
}

.table-scroll th {
  position: sticky;
  inset-block-start: 0;
  z-index: 1;
  background: Canvas;
}
```

### Caption [#caption]

```css
.table caption {
  caption-side: bottom;
  padding-block: 0.5rem;
  color: color-mix(in oklab, CanvasText 65%, transparent);
  text-align: start;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Building “tables” from divs for data, losing row/column semantics for assistive tech.
* Mixing `border-collapse: collapse` with `border-radius` expectations—radius often won’t apply as on separate boxes.
* Letting wide tables overflow the viewport without a scroll wrapper or responsive strategy.
* Sticky headers failing because a parent uses `overflow: hidden`.
* Aligning numbers to the start, which makes columns hard to scan—use end alignment + tabular nums.

## 🔗 Related [#-related]

* [Text](/docs/css/text)
* [Scroll](/docs/css/scroll)
* [CSS Grid](/docs/css/grid)
* [Fonts](/docs/css/font)


---

# Text (/docs/css/text)



# Text [#text]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Text CSS controls wrapping, alignment, decoration, spacing, overflow, and white-space behavior. It sits beside font properties: fonts choose the face; text properties shape how glyphs flow in a box. Use these tools for readable paragraphs, truncated labels, wrapping balance, and decorative underlines without breaking accessibility or copy-paste.

Prefer logical alignment (`text-align: start`) and modern wrapping (`overflow-wrap`, `text-wrap`) for internationalized UIs.

## 🔧 Core concepts [#-core-concepts]

### Alignment & direction [#alignment--direction]

| Property                     | Notes                                                          |
| ---------------------------- | -------------------------------------------------------------- |
| `text-align`                 | `start` \| `end` \| `left` \| `right` \| `center` \| `justify` |
| `text-align-last`            | Last line alignment                                            |
| `direction` / `unicode-bidi` | Prefer HTML `dir` attribute when possible                      |
| `writing-mode`               | `horizontal-tb` \| `vertical-rl` \| …                          |
| `text-orientation`           | Vertical text glyph orientation                                |

### Wrapping & overflow [#wrapping--overflow]

| Property                       | Role                                                                        |
| ------------------------------ | --------------------------------------------------------------------------- |
| `white-space`                  | `normal` \| `nowrap` \| `pre` \| `pre-wrap` \| `pre-line` \| `break-spaces` |
| `overflow-wrap` / `word-break` | Long-string breaking strategies                                             |
| `line-break`                   | CJK line breaking                                                           |
| `hyphens`                      | `none` \| `manual` \| `auto` (needs `lang`)                                 |
| `text-overflow`                | `clip` \| `ellipsis` (needs overflow + nowrap typically)                    |
| `text-wrap`                    | `wrap` \| `balance` \| `pretty` \| `nowrap` (modern)                        |

### Decoration & spacing [#decoration--spacing]

| Property                          | Role                                                 |
| --------------------------------- | ---------------------------------------------------- |
| `text-decoration-*`               | line, style, color, thickness                        |
| `text-underline-offset`           | Optical underline position                           |
| `letter-spacing` / `word-spacing` | Tracking                                             |
| `text-indent`                     | First-line indent                                    |
| `text-transform`                  | `uppercase` \| `lowercase` \| `capitalize` \| `none` |
| `hanging-punctuation`             | Optical margin hanging (limited support)             |

## 💡 Examples [#-examples]

### Readable measure [#readable-measure]

```css
.prose {
  max-inline-size: 65ch;
  text-wrap: pretty;
  line-height: 1.6;
}

.prose h2 {
  text-wrap: balance;
}
```

### Truncate single line [#truncate-single-line]

```css
.truncate {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  max-inline-size: 100%;
}
```

### Clamp to N lines [#clamp-to-n-lines]

```css
.line-clamp-3 {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}
```

### Link underline polish [#link-underline-polish]

```css
.prose a {
  text-decoration: underline;
  text-decoration-thickness: 0.08em;
  text-underline-offset: 0.18em;
  text-decoration-color: color-mix(in oklab, currentColor 55%, transparent);
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Justifying text on narrow columns without hyphenation, creating huge word gaps.
* Using `word-break: break-all` on normal prose, which shreds readability.
* Truncating with ellipsis without another way to read the full string (title, expand, dialog).
* Applying `text-transform: uppercase` for logos/headings that screen readers may still announce oddly—prefer real content casing when meaning matters.
* Setting `letter-spacing` large on body text, harming readability.

## 🔗 Related [#-related]

* [Fonts](/docs/css/font)
* [Text fields](/docs/css/textfield)
* [Buttons](/docs/css/button)
* [Multi-column layout](/docs/css/column)


---

# Text fields (/docs/css/textfield)



# Text fields [#text-fields]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Text field styling covers `<input>` (text-like types), `<textarea>`, and contenteditable surfaces. Native controls inherit inconsistently across browsers, so production UIs usually apply a shared reset: font inheritance, explicit padding, borders, and focus styles. Prioritize visible labels, `:focus-visible` rings, error states, and comfortable touch targets over purely decorative chrome.

Use logical padding and `min-block-size` so fields scale with user font settings.

## 🔧 Core concepts [#-core-concepts]

### Elements & types [#elements--types]

| Control              | Notes                            |     |        |          |     |           |                    |
| -------------------- | -------------------------------- | --- | ------ | -------- | --- | --------- | ------------------ |
| \`input\[type="text" | email                            | url | search | password | tel | number]\` | Single-line fields |
| `textarea`           | Multi-line; style `resize`       |     |        |          |     |           |                    |
| `input[type="file"]` | Limited styling; often wrapped   |     |        |          |     |           |                    |
| `::placeholder`      | Hint text; never replace a label |     |        |          |     |           |                    |
| `::selection`        | Selected text colors             |     |        |          |     |           |                    |

### Useful properties [#useful-properties]

| Property                            | Role                                                 |
| ----------------------------------- | ---------------------------------------------------- |
| `font: inherit`                     | Match UI typography                                  |
| `appearance` / `-webkit-appearance` | Reduce native look where needed                      |
| `caret-color`                       | Caret theming                                        |
| `field-sizing`                      | `fixed` \| `content` (modern auto-size inputs/areas) |
| `resize`                            | `none` \| `vertical` \| `both` on textareas          |
| `accent-color`                      | Some controls’ accent (checkboxes, etc.)             |

### State selectors [#state-selectors]

| Selector                     | Use                                         |
| ---------------------------- | ------------------------------------------- |
| `:focus-visible`             | Keyboard-friendly focus ring                |
| `:user-invalid` / `:invalid` | Validation styling (prefer user-interacted) |
| `:disabled` / `:read-only`   | Non-editable affordances                    |
| `:placeholder-shown`         | Empty field styling                         |

## 💡 Examples [#-examples]

### Baseline field [#baseline-field]

```css
.field {
  display: grid;
  gap: 0.35rem;
}

.field__input {
  font: inherit;
  line-height: 1.4;
  padding: 0.625rem 0.75rem;
  min-block-size: 2.5rem;
  border: 1px solid color-mix(in oklab, CanvasText 20%, transparent);
  border-radius: 0.5rem;
  background: Canvas;
  color: CanvasText;
  inline-size: 100%;
}

.field__input::placeholder {
  color: color-mix(in oklab, CanvasText 45%, transparent);
}

.field__input:focus-visible {
  outline: 2px solid oklch(0.65 0.15 250);
  outline-offset: 2px;
  border-color: transparent;
}
```

### Textarea [#textarea]

```css
.field__input--area {
  min-block-size: 6rem;
  resize: vertical;
  field-sizing: content; /* progressive enhancement */
}
```

### Error state [#error-state]

```css
.field__input[aria-invalid="true"] {
  border-color: oklch(0.55 0.2 25);
}

.field__error {
  color: oklch(0.5 0.18 25);
  font-size: 0.875rem;
}
```

### Search with icon padding [#search-with-icon-padding]

```css
.input-search {
  padding-inline-start: 2.25rem;
  background-image: url("/icons/search.svg");
  background-repeat: no-repeat;
  background-position: left 0.65rem center;
  background-size: 1rem;
}

[dir="rtl"] .input-search {
  background-position: right 0.65rem center;
  padding-inline-start: 0.75rem;
  padding-inline-end: 2.25rem;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Removing focus outlines without a strong `:focus-visible` replacement.
* Using placeholder text as the only label—placeholders disappear and hurt accessibility.
* Styling `:invalid` from page load (before user input), which marks empty required fields red immediately—prefer `:user-invalid` where supported.
* Forbidding `resize` on large textareas without another way to grow the control.
* Setting fixed `height` in `px` that clips descenders or breaks zoomed text.

## 🔗 Related [#-related]

* [Buttons](/docs/css/button)
* [Text](/docs/css/text)
* [Fonts](/docs/css/font)
* [Cursor](/docs/css/cursor)


---

# Transforms (/docs/css/transform)



# Transforms [#transforms]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

CSS transforms move, rotate, scale, and skew elements in 2D or 3D without necessarily reflowing the document. They are the foundation of performant UI motion when paired with `opacity`. Prefer the individual transform properties (`translate`, `rotate`, `scale`) for readable code, or the classic `transform` list when you need a precise composed matrix order.

Transforms create a containing block for fixed descendants and often a new stacking context—account for that when building overlays.

## 🔧 Core concepts [#-core-concepts]

### Individual vs shorthand [#individual-vs-shorthand]

| Property    | Example                                               |
| ----------- | ----------------------------------------------------- |
| `translate` | `translate: 0 0.5rem` or `translate: 10% 0 2rem` (3D) |
| `rotate`    | `rotate: 15deg` or `rotate: x 45deg`                  |
| `scale`     | `scale: 1.05` / `scale: 1.1 0.9`                      |
| `transform` | `transform: translateY(0.5rem) rotate(3deg)`          |

Used transform combines individual properties with `transform` according to CSS Transforms Module rules—avoid setting conflicting systems blindly.

### Common transform functions [#common-transform-functions]

| Function                                             | Role                                                      |
| ---------------------------------------------------- | --------------------------------------------------------- |
| `translate()` / `translateX/Y/Z()` / `translate3d()` | Move                                                      |
| `scale()` / `scaleX/Y/Z()`                           | Resize visually                                           |
| `rotate()` / `rotateX/Y/Z()` / `rotate3d()`          | Rotate                                                    |
| `skew()` / `skewX/Y()`                               | Oblique distortion                                        |
| `matrix()` / `matrix3d()`                            | Raw matrix                                                |
| `perspective()`                                      | As a function on the element (often use property instead) |

### 3D helpers [#3d-helpers]

| Property              | Role                             |
| --------------------- | -------------------------------- |
| `perspective`         | On parent: depth for 3D children |
| `perspective-origin`  | Vanishing point                  |
| `transform-style`     | `flat` \| `preserve-3d`          |
| `backface-visibility` | `visible` \| `hidden`            |
| `transform-origin`    | Pivot point                      |

## 💡 Examples [#-examples]

### Enter transition with translate + opacity [#enter-transition-with-translate--opacity]

```css
.drawer {
  translate: 0 100%;
  opacity: 0;
  transition: translate 240ms ease, opacity 240ms ease;
}

.drawer.is-open {
  translate: 0 0;
  opacity: 1;
}
```

### Classic transform list [#classic-transform-list]

```css
.badge {
  transform: translateY(-50%) rotate(-6deg);
  transform-origin: left center;
}
```

### 3D card flip [#3d-card-flip]

```css
.flip {
  perspective: 800px;
}

.flip__inner {
  position: relative;
  transform-style: preserve-3d;
  transition: transform 500ms ease;
}

.flip.is-flipped .flip__inner {
  transform: rotateY(180deg);
}

.flip__face {
  backface-visibility: hidden;
}

.flip__face--back {
  transform: rotateY(180deg);
}
```

### GPU-friendly hover lift [#gpu-friendly-hover-lift]

```css
.tile {
  transition: transform 150ms ease, box-shadow 150ms ease;
}

@media (hover: hover) {
  .tile:hover {
    transform: translateY(-4px);
  }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Animating `top`/`left` instead of `translate`, causing layout thrashing.
* Surprising `position: fixed` children when an ancestor gains a transform.
* Using `skew` for primary layout alignment—text becomes harder to read.
* Forgetting `transform-origin` on rotations so UI pivots from the wrong point.
* Enabling `preserve-3d` and large blurs/filters on many nodes, which is expensive.

## 🔗 Related [#-related]

* [Scale](/docs/css/scale)
* [Animation](/docs/css/animation)
* [Positioning](/docs/css/position)
* [Effects](/docs/css/effects)


---

# Transitions (/docs/css/transitions)



# Transitions [#transitions]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Transitions interpolate property changes over time when a value changes (hover, class toggle, JS). Prefer transitions for simple state changes; use `@keyframes` animations for looping or multi-step sequences. Respect `prefers-reduced-motion`.

## 🔧 Core concepts [#-core-concepts]

* **Shorthand**: `transition: property duration easing delay`.
* **Longhands**: `transition-property`, `-duration`, `-timing-function`, `-delay`, `-behavior`.
* **Properties**: animatable values (colors, lengths, opacity, transforms…). Discrete props flip (with `transition-behavior: allow-discrete` for some).
* **Easing**: `ease`, `linear`, `ease-in-out`, `cubic-bezier()`, `steps()`.
* **`transitionend` / `transitioncancel`**: JS hooks.
* **Best perf**: `transform` and `opacity` (compositor-friendly).

```css
.button {
  transition:
    background-color 150ms ease,
    transform 150ms ease;
}
.button:hover {
  transform: translateY(-1px);
}
```

## 💡 Examples [#-examples]

```css
/* Multiple */
.card {
  transition:
    box-shadow 200ms ease,
    transform 200ms ease;
}

/* Delay for staggered menus */
.menu a {
  transition: opacity 120ms ease;
  transition-delay: calc(var(--i, 0) * 40ms);
}

/* Height auto — modern interpolate-size / grid trick */
.panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 200ms ease;
}
.panel.open {
  grid-template-rows: 1fr;
}
.panel > * {
  overflow: hidden;
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
  }
}
```

```js
el.addEventListener("transitionend", (e) => {
  if (e.propertyName === "opacity") el.hidden = true;
});
```

## ⚠️ Pitfalls [#️-pitfalls]

* `transition: all` is convenient but can animate expensive properties unintentionally.
* Cannot smoothly transition to/from `height: auto` in older engines — use grid/max-height hacks or new CSS features.
* Changing `transition` itself mid-flight can cancel — set transition on base rule, change property on state.
* Display `none` ↔ visible needs care (`allow-discrete` / `@starting-style`).
* Too-long transitions feel sluggish — UI micro-interactions often 100–200ms.

## 🔗 Related [#-related]

* [animation.md](/docs/css/animation) — keyframes
* [transform.md](/docs/css/transform) — transform props
* [effects.md](/docs/css/effects) — shadows/filters
* [hover.md](/docs/css/hover) — hover triggers
* [dark\_mode.md](/docs/css/dark-mode) — theme transitions


---

# CSS Variables (/docs/css/variables)



# CSS Variables [#css-variables]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Custom properties (`--name`) store reusable values that cascade and inherit. They enable theming, runtime tweaks via JS, and cleaner design tokens. Declare on `:root` or a scope; use with `var(--name, fallback)`.

## 🔧 Core concepts [#-core-concepts]

* **Define**: `--accent: #3366ff;` on any element.
* **Use**: `color: var(--accent);` / `var(--accent, blue)`.
* **Inheritance**: custom props inherit by default; reset with `initial` or new value.
* **Scope**: set on a component host to theme a subtree.
* **Computation**: can hold any token sequence; invalid at computed-value time falls back.
* **JS**: `element.style.setProperty("--x", "1rem")`, `getComputedStyle(el).getPropertyValue("--x")`.

```css
:root {
  --space: 0.5rem;
  --text: #111;
  --accent: oklch(60% 0.2 250);
}
.button {
  padding: calc(var(--space) * 2);
  color: var(--text);
  background: var(--accent);
}
```

## 💡 Examples [#-examples]

```css
/* Theming */
html[data-theme="dark"] {
  --text: #f5f5f5;
  --bg: #121212;
}
body {
  color: var(--text);
  background: var(--bg);
}

/* Component tokens */
.card {
  --card-pad: 1rem;
  padding: var(--card-pad);
}
.card.compact {
  --card-pad: 0.5rem;
}

/* Fallback chain */
color: var(--brand, var(--accent, navy));

/* With relative color / calc */
--h: 200;
background: oklch(70% 0.1 var(--h));
width: calc(100% - var(--sidebar, 0px));
```

```js
document.documentElement.style.setProperty("--accent", userColor);
```

## ⚠️ Pitfalls [#️-pitfalls]

* `--x: 10` without units breaks `calc` expecting lengths — store units in the variable or multiply carefully.
* Custom properties are not CSS variables in the preprocessor sense — invalid values fail at computed-value time.
* Animating custom props needs `@property` for typed interpolation in many cases.
* Overusing global tokens without scopes creates coupling.
* `var()` inside URLs / some older contexts has quirks — test.

## 🔗 Related [#-related]

* [color\_functions.md](/docs/css/color-functions) — modern colors
* [calc\_min\_max\_clamp.md](/docs/css/calc-min-max-clamp) — calc with vars
* [dark\_mode.md](/docs/css/dark-mode) — theme switching
* [cascade\_layers.md](/docs/css/cascade-layers) — cascade order
* [specificity.md](/docs/css/specificity) — vs !important


---

# z-index (/docs/css/z-index)



# z-index [#z-index]

*CSS · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`z-index` controls stacking order **within a stacking context**. Only positioned elements (`relative`/`absolute`/`fixed`/`sticky`) or flex/grid items (and some properties that create contexts) participate. Most z-index bugs are stacking-context bugs, not number-size bugs.

## 🔧 Core concepts [#-core-concepts]

* **Stacking context roots**: `html`, `z-index` ≠ auto on positioned/flex/grid, `opacity &lt; 1`, `transform`, `filter`, `isolation: isolate`, `will-change`, etc.
* **Children** cannot escape a parent’s context to sit above an uncle — raise/isolate the parent.
* **Auto vs integer**: `auto` doesn’t create a new context by itself (with position); integers do on positioned elements.
* **Painting order**: backgrounds/borders → negative z → in-flow → floats → in-flow inline → z=auto/0 → positive z.
* **Strategy**: use small scales (0–10) + `isolation` rather than `99999`.

```css
.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 10;
}
.modal {
  position: fixed;
  z-index: 11;
}
```

## 💡 Examples [#-examples]

```css
/* Isolate a component */
.dropdown {
  position: relative;
  isolation: isolate;
  z-index: 1;
}
.dropdown-menu {
  position: absolute;
  z-index: 2; /* only competes inside dropdown */
}

/* Sticky header */
.header {
  position: sticky;
  top: 0;
  z-index: 5;
}

/* Trap: transformed parent */
.parent {
  transform: translateZ(0);
} /* new context */
.child {
  position: relative;
  z-index: 9999;
} /* still under sibling contexts of parent */

/* Flex item z-index without position */
.row > .raise {
  z-index: 1;
}
```

```css
/* Debug layers with outline + temporary z */
```

## ⚠️ Pitfalls [#️-pitfalls]

* Huge `z-index` values don’t beat a parent stacking context.
* `opacity`, `transform`, `filter`, `backdrop-filter` create contexts — surprising for tooltips/modals.
* Mixing stacking from different features (sticky + transform) causes hard bugs — simplify.
* Negative z-index can hide behind the parent’s background.
* Accessibility: visual order ≠ tab order — don’t fake UI order only with z-index.

## 🔗 Related [#-related]

* [position.md](/docs/css/position) — positioning schemes
* [sticky.md](/docs/css/sticky) — sticky stacking
* [filter\_backdrop.md](/docs/css/filter-backdrop) — context creators
* [overflow.md](/docs/css/overflow) — clipping vs stack
* [transform.md](/docs/css/transform) — transform contexts

