css-responsive

Modern responsive design using container queries, fluid typography, responsive images, logical properties, viewport units, intrinsic sizing, and preference queries. Prioritizes container queries over media queries. Use when the user asks for responsive CSS, responsive design, mobile layout, fluid typography, responsive images, dark mode, prefers-reduced-motion, or adaptive design.

Best use case

css-responsive is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Modern responsive design using container queries, fluid typography, responsive images, logical properties, viewport units, intrinsic sizing, and preference queries. Prioritizes container queries over media queries. Use when the user asks for responsive CSS, responsive design, mobile layout, fluid typography, responsive images, dark mode, prefers-reduced-motion, or adaptive design.

Teams using css-responsive should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/css-responsive/SKILL.md --create-dirs "https://raw.githubusercontent.com/Lionad-Morotar/local-tools/main/local-link/skills/css-dev-skills/skills/css-responsive/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/css-responsive/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How css-responsive Compares

Feature / Agentcss-responsiveStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Modern responsive design using container queries, fluid typography, responsive images, logical properties, viewport units, intrinsic sizing, and preference queries. Prioritizes container queries over media queries. Use when the user asks for responsive CSS, responsive design, mobile layout, fluid typography, responsive images, dark mode, prefers-reduced-motion, or adaptive design.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# css.dev — CSS Responsive

You are a senior CSS engineer specializing in responsive design. Build responsive layouts and components using modern techniques. Always generate code. Prefer intrinsic sizing and container queries over breakpoint-driven media queries. For reference, see [modern-patterns.md](../css-expert/references/modern-patterns.md) and [browser-compat.md](../css-expert/references/browser-compat.md).

## Workflow

1. **Understand the target** — Is this a page-level layout or a component? Components use container queries. Pages use media queries.
2. **Start fluid** — Use `clamp()`, intrinsic sizing, and flexible grids so most things just work without breakpoints.
3. **Add container queries** — For components that need layout changes based on their container size.
4. **Add media queries** — Only for page-level layout shifts (sidebar collapse, navigation pattern change).
5. **Add preference queries** — Color scheme, reduced motion, contrast.
6. **Handle images** — Use `srcset`, `sizes`, and `<picture>` for responsive images.

## Responsive Strategy Hierarchy

Apply in this order — each layer reduces the need for the next:

```
1. Intrinsic sizing     → content determines size naturally
2. Fluid values         → clamp() adapts without breakpoints
3. Flexible layouts     → Grid/Flexbox auto-fill, wrap, grow
4. Container queries    → component adapts to its container
5. Media queries        → page-level layout shifts only
```

## Container Queries

### When to Use

- A component's layout should change based on **its container**, not the viewport.
- Cards, widgets, sidebars, navigation items — anything reusable.

### Setup

```css
.component-wrapper {
  container-type: inline-size;
  container-name: card;
}
```

### Responsive Component

```css
.card-wrapper {
  container-type: inline-size;
}

.card {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);

  @container (inline-size >= 450px) {
    flex-direction: row;
    align-items: center;
  }

  @container (inline-size >= 700px) {
    display: grid;
    grid-template-columns: 250px 1fr auto;
  }
}
```

### Container Query Units

| Unit | Meaning |
|------|---------|
| `cqi` | 1% of container inline size |
| `cqb` | 1% of container block size |
| `cqmin` | smaller of `cqi` and `cqb` |
| `cqmax` | larger of `cqi` and `cqb` |

```css
.card-title {
  font-size: clamp(1rem, 3cqi, 1.5rem);
}
```

### Named Containers

```css
.sidebar {
  container-type: inline-size;
  container-name: sidebar;
}

@container sidebar (inline-size > 300px) {
  .widget { display: grid; grid-template-columns: 1fr 1fr; }
}
```

## Media Queries (Page Level Only)

Use media queries only for page-level layout shifts.

### Correct Usage

```css
@media (max-width: 48em) {
  .page {
    grid-template-columns: 1fr;
  }
  .sidebar { display: none; }
}
```

### Rules

- Use `em` units, never `px` — respects user font size.
- Prefer `min-width` (mobile-first) unless the desktop layout is simpler.
- Limit to 2–3 breakpoints maximum for page layout.
- Never use media queries for component-level responsiveness.

### Recommended Breakpoints (if needed)

```css
/* Compact */    @media (max-width: 48em) { }
/* Medium */     @media (min-width: 48em) and (max-width: 64em) { }
/* Expanded */   @media (min-width: 64em) { }
```

## Fluid Typography

Use `clamp()` for font sizes that scale smoothly between a minimum and maximum.

### Type Scale

```css
:root {
  --text-sm:  clamp(0.8rem, 0.75rem + 0.25vw, 0.875rem);
  --text-base: clamp(1rem, 0.925rem + 0.375vw, 1.125rem);
  --text-lg:  clamp(1.125rem, 1rem + 0.625vw, 1.375rem);
  --text-xl:  clamp(1.25rem, 1.1rem + 0.75vw, 1.625rem);
  --text-2xl: clamp(1.5rem, 1.25rem + 1.25vw, 2.25rem);
  --text-3xl: clamp(2rem, 1.5rem + 2.5vw, 3.5rem);
}
```

### How clamp() Works

```
clamp(minimum, preferred, maximum)
```

- **minimum**: smallest the value can be (in `rem`)
- **preferred**: scales with viewport (use `rem + vw`)
- **maximum**: largest the value can be (in `rem`)

### Fluid Spacing Scale

```css
:root {
  --space-xs: clamp(0.5rem, 0.4rem + 0.5vw, 0.75rem);
  --space-s:  clamp(0.75rem, 0.6rem + 0.75vw, 1rem);
  --space-m:  clamp(1rem, 0.8rem + 1vw, 1.5rem);
  --space-l:  clamp(1.5rem, 1.2rem + 1.5vw, 2rem);
  --space-xl: clamp(2rem, 1.6rem + 2vw, 3rem);
  --space-2xl: clamp(3rem, 2.4rem + 3vw, 4.5rem);
}
```

## Responsive Images

### srcset + sizes

```html
<img
  src="image-800.jpg"
  srcset="
    image-400.jpg 400w,
    image-800.jpg 800w,
    image-1200.jpg 1200w,
    image-1600.jpg 1600w
  "
  sizes="
    (max-width: 48em) 100vw,
    (max-width: 64em) 50vw,
    33vw
  "
  alt="Description"
  loading="lazy"
  decoding="async"
>
```

### Art Direction with `<picture>`

```html
<picture>
  <source
    media="(min-width: 64em)"
    srcset="hero-wide.avif"
    type="image/avif"
  >
  <source
    media="(min-width: 48em)"
    srcset="hero-medium.avif"
    type="image/avif"
  >
  <img
    src="hero-narrow.jpg"
    alt="Description"
    loading="lazy"
    decoding="async"
  >
</picture>
```

### Responsive Image CSS

```css
img {
  max-inline-size: 100%;
  block-size: auto;
  display: block;
}

.hero-image {
  inline-size: 100%;
  block-size: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}
```

## Viewport Units

### Modern Viewport Units

| Unit | Meaning |
|------|---------|
| `dvh` | Dynamic viewport height (accounts for mobile browser chrome) |
| `svh` | Small viewport height (smallest possible viewport) |
| `lvh` | Large viewport height (largest possible viewport) |
| `dvw` | Dynamic viewport width |

### Usage

```css
.full-screen {
  min-block-size: 100dvh;
}

.hero {
  block-size: 100svh;
}
```

- Use `dvh` for full-height layouts on mobile (accounts for URL bar).
- Use `svh` when you need the element to never exceed the visible area.
- Never use `100vh` — it doesn't account for mobile browser UI.

## Intrinsic Sizing

### min(), max(), clamp()

```css
.container {
  inline-size: min(90%, 75rem);
  margin-inline: auto;
}

.card-grid {
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
}

.sidebar {
  inline-size: clamp(200px, 25%, 350px);
}
```

### fit-content

```css
.tag {
  inline-size: fit-content;
  padding-inline: var(--space-s);
}
```

### min-content / max-content

```css
.nav { inline-size: max-content; }
.label { inline-size: min-content; }
```

## Logical Properties

Use logical properties for all directional values. They support RTL/LTR automatically.

```css
.element {
  margin-block: var(--space-m);
  padding-inline: var(--space-l);
  border-inline-start: 3px solid var(--color-primary);
  max-inline-size: 65ch;
  text-align: start;
}
```

Full mapping reference in the [css-layout](../css-layout/SKILL.md) skill.

## Preference Queries

### Color Scheme

```css
:root {
  color-scheme: light dark;
  --color-surface: light-dark(white, oklch(15% 0 0));
  --color-text: light-dark(oklch(20% 0 0), oklch(90% 0 0));
  --color-border: light-dark(oklch(80% 0 0), oklch(30% 0 0));
}
```

`light-dark()` is preferred over `@media (prefers-color-scheme)` for individual values. Use the media query only for structural changes:

```css
@media (prefers-color-scheme: dark) {
  .logo { filter: brightness(1.2); }
}
```

### Reduced Motion

```css
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
```

### High Contrast

```css
@media (prefers-contrast: more) {
  :root {
    --color-border: oklch(0% 0 0);
    --color-text: oklch(0% 0 0);
  }

  .card {
    border: 2px solid var(--color-border);
  }
}
```

### Forced Colors (Windows High Contrast)

```css
@media (forced-colors: active) {
  .button {
    border: 2px solid ButtonText;
  }

  .icon {
    forced-color-adjust: none;
  }
}
```

### Reduced Transparency

```css
@media (prefers-reduced-transparency: reduce) {
  .overlay {
    background: var(--color-surface);
    backdrop-filter: none;
  }
}
```

## Responsive Spacing Scale

Use `clamp()` for spacing that scales between viewports without breakpoints:

```css
:root {
  --space-xs: clamp(0.5rem, 0.4rem + 0.5vw, 0.75rem);
  --space-s:  clamp(0.75rem, 0.6rem + 0.75vw, 1rem);
  --space-m:  clamp(1rem, 0.8rem + 1vw, 1.5rem);
  --space-l:  clamp(1.5rem, 1.2rem + 1.5vw, 2rem);
  --space-xl: clamp(2rem, 1.6rem + 2vw, 3rem);
}

section { padding-block: var(--space-xl); }
.stack > * + * { margin-block-start: var(--space-m); }
```

## Checklist Before Delivering

- [ ] Container queries used for component responsiveness (not media queries)
- [ ] Media queries limited to page-level layout shifts
- [ ] Media queries use `em` units (not `px`)
- [ ] Font sizes use `clamp()` with `rem` + `vw`
- [ ] Spacing uses fluid scale with custom properties
- [ ] Logical properties used (no `left`/`right`/`top`/`bottom`)
- [ ] Images use `srcset`/`sizes` or `<picture>` where appropriate
- [ ] `100dvh` used instead of `100vh`
- [ ] `prefers-reduced-motion` handled
- [ ] `prefers-color-scheme` handled (or `light-dark()`)
- [ ] `prefers-contrast` handled for key elements
- [ ] No fixed widths — intrinsic sizing with `min()`/`max()`/`clamp()`
- [ ] Content is readable at 320px and 2560px viewports

Related Skills

open-u-dashboard

7
from Lionad-Morotar/local-tools

open understand dashboard for user

sync-template-skill

7
from Lionad-Morotar/local-tools

这是一个技能文件的模板,展示了技能的基本结构和内容组织方式。

talk-humanize

7
from Lionad-Morotar/local-tools

Be direct and informative. No filler, no fluff, but give enough to be useful.

search-web

7
from Lionad-Morotar/local-tools

使用 Evaluator-optimizer 模式进行系统性多轮网络搜索,采用结构化 Ask 流程在搜索前澄清研究目标。基于 YC Office Hours 的提问方法论,确保搜索方向清晰、结果可验证。当用户需要深入调查复杂主题、验证假设或全面收集信息时使用。

save-to-eagle

7
from Lionad-Morotar/local-tools

归档网络内容到 Eagle 素材库。支持:(1) Behance/Pixiv 图片归档,(2) 网页视频录制(页面动画、滚动录制)。使用方式:'归档 [URL]' 归档图片;'录制网页视频 [URL]' 录制页面动画;'滚动录制 [URL]' 自动滚动截图。支持评分如 '归档 [URL], 3/5'。

save-ob-chaos

7
from Lionad-Morotar/local-tools

将对话内容快速存档到 Obsidian Chaos 文件夹。触发词:"存档到 Obsidian"、"保存到 Chaos"、"ob 存档"、"记下这个"、"保存这段内容"、"存到 chaos"。

save-ob-chaos-mermaid

7
from Lionad-Morotar/local-tools

将 Mermaid 图表保存到 Obsidian Chaos 文件夹。触发词:"保存 mermaid 到 chaos"、"mermaid 存档"。

save-ob-chaos-excalidraw

7
from Lionad-Morotar/local-tools

绘制 Excalidraw 图表并存档到 Obsidian Chaos 文件夹。触发词:"画个图存到 Obsidian"、"excalidraw 存档"、"画个流程图保存"、"画图存到 chaos"、"创建图表并存档"、"画架构图到 ob"。

release-project

7
from Lionad-Morotar/local-tools

项目版本发布流程指导,帮助用户完成版本规划、Changelog 管理、版本号升级、Git 标签创建和 npm 首次发布准备。Use when: (1) 用户需要发布新版本 (2) 需要创建版本发布流程 (3) 需要管理版本号和 Changelog (4) 需要自动化版本发布 (5) 需要检查 release 分支同步 (6) 首次 npm 发布准备

recognize-codebase-branch-flow

7
from Lionad-Morotar/local-tools

识别并记忆项目 git 分支模型

rebase-commits

7
from Lionad-Morotar/local-tools

将零散的 commits 整合为清晰的逻辑提交,使 Git 历史更易读。 Use when: (1) 用户说 "rebase commits"、"整理提交历史"、"让历史更干净" (2) 用户想将多个相关 commits 合并为逻辑单元 (3) 完成一个功能后需要清理 commit 历史 (4) 提交历史混乱,需要重新组织

read-codebase

7
from Lionad-Morotar/local-tools

阅读棕地项目代码库,智能分析代码结构,递归补充其调用链上所有函数的注释。