Media queries com Claude Code: guia CSS prático
Implemente CSS responsivo com Claude Code: media queries, container queries, preferências e testes Playwright.
Uma página pode parecer perfeita no notebook e falhar no ponto que gera resultado: leitura no celular, cartão de afiliado dentro de uma coluna estreita, modo escuro ou tela administrativa usada por horas. Pedir ao Claude Code “deixe responsivo” é amplo demais. O melhor é entregar regras de layout, preferências de usuário e uma forma de validar.
Media query aplica CSS quando o ambiente do navegador atende a uma condição. Container query aplica CSS conforme o tamanho do contêiner pai do componente. prefers-reduced-motion e prefers-color-scheme respeitam escolhas do sistema do leitor. Use as fontes oficiais: MDN CSS media queries, Using media queries, CSS container queries, CSSWG Media Queries Level 5, W3C CSS Containment Module Level 3 e Playwright emulation.
Para base, leia também CSS Grid com Claude Code, padrões Flexbox, acessibilidade e performance.
Regra principal
Comece mobile-first. O layout pequeno é o CSS padrão; telas maiores recebem ajustes com @media (width >= 48rem). Não escolha breakpoints por nomes de aparelhos. Escolha quando o conteúdo começa a sofrer: navegação quebra mal, cards ficam apertados, anúncios encostam no texto ou formulários ficam difíceis de ler.
| Decisão | Media queries | Container queries |
|---|---|---|
| Observa | Viewport, impressão, preferências | Tamanho ou estado do contêiner pai |
| Melhor uso | Layout da página, navegação, espaçamento global | Cards, CTA, preços, UI reutilizável |
| Erro comum | Breakpoints por aparelho demais | Esquecer container-type |
| Prompt | “Mude o layout pela largura do viewport” | “Mude o card pela largura disponível” |
Casos reais
Em um artigo de blog, empilhe texto, CTA e relacionados no celular. Adicione sidebar só quando houver largura suficiente. Cards de afiliado e produto devem usar container queries para funcionar no corpo, na sidebar e em blocos relacionados.
Em uma página de preços SaaS, o mesmo card aparece na home, landing page e checkout. Se o CSS olhar apenas para o viewport, o card pode assumir layout largo dentro de uma coluna estreita.
Em um painel administrativo, filtros, tabela, exportação e busca competem por espaço. Em telas pequenas, a tabela pode virar cards; em telas largas, mantém colunas. prefers-reduced-motion evita movimento cansativo em uso prolongado.
Em conteúdo monetizado, CTAs precisam aparecer sem esmagar a leitura. Use media queries para o ritmo da página e container queries para o interior do CTA.
HTML/CSS para copiar
Salve como responsive-demo.html e abra no navegador. O exemplo usa mobile-first, container queries, modo escuro, redução de movimento e tipografia com clamp(). Evite font-size: 4vw; o texto pode ficar gigante em telas largas e pequeno em telas estreitas.
<!doctype html>
<html lang="pt">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Responsive media query demo</title>
<style>
:root { color-scheme: light dark; --bg: #f7f8fb; --surface: #ffffff; --text: #1f2937; --line: #d8dee8; --accent: #0f766e; --accent-strong: #115e59; --shadow: 0 12px 30px rgb(15 23 42 / 0.12); }
* { box-sizing: border-box; }
body { margin: 0; font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; font-size: clamp(1rem, 0.94rem + 0.25vw, 1.125rem); line-height: 1.7; color: var(--text); background: var(--bg); }
a { color: var(--accent-strong); }
.site-header { padding: 1rem; border-bottom: 1px solid var(--line); background: var(--surface); position: sticky; top: 0; z-index: 10; }
.nav { display: flex; flex-wrap: wrap; gap: 0.75rem 1rem; align-items: center; justify-content: space-between; max-width: 72rem; margin: 0 auto; }
.brand { font-weight: 800; }
.nav-links { display: flex; gap: 0.75rem; padding: 0; margin: 0; list-style: none; }
.page { width: min(100% - 2rem, 72rem); margin: 2rem auto; display: grid; gap: 1.5rem; }
.hero, .article, .sidebar-card, .offer { background: var(--surface); border: 1px solid var(--line); border-radius: 8px; box-shadow: var(--shadow); }
.hero { padding: clamp(1.25rem, 1rem + 1.5vw, 2.5rem); }
h1 { margin: 0 0 0.75rem; font-size: clamp(2rem, 1.65rem + 1.6vw, 3.2rem); line-height: 1.15; }
.layout { display: grid; gap: 1.5rem; }
.article, .sidebar-card { padding: 1rem; }
.sidebar { display: grid; gap: 1rem; align-content: start; }
.offer-wrap { container-type: inline-size; container-name: offer; }
.offer { display: grid; gap: 1rem; padding: 1rem; overflow: hidden; }
.offer-media { min-height: 10rem; border-radius: 6px; background: linear-gradient(135deg, rgb(15 118 110 / 0.85), rgb(37 99 235 / 0.75)), repeating-linear-gradient(45deg, rgb(255 255 255 / 0.18) 0 10px, transparent 10px 20px); }
.button { display: inline-flex; width: fit-content; min-height: 2.75rem; align-items: center; justify-content: center; padding: 0.7rem 1rem; border-radius: 6px; background: var(--accent); color: white; font-weight: 700; text-decoration: none; transition: transform 180ms ease, background-color 180ms ease; }
.button:hover { transform: translateY(-2px); background: var(--accent-strong); }
@media (width >= 48rem) { .article { padding: 1.5rem; } .layout { grid-template-columns: minmax(0, 1fr) 18rem; align-items: start; } }
@media (width >= 72rem) { .layout { grid-template-columns: minmax(0, 2fr) minmax(18rem, 0.8fr); } }
@container offer (width >= 34rem) { .offer { grid-template-columns: 14rem minmax(0, 1fr); align-items: center; padding: 1.25rem; } }
@media (prefers-color-scheme: dark) { :root { --bg: #10151f; --surface: #18202d; --text: #eef2f7; --line: #334155; --accent: #2dd4bf; --accent-strong: #5eead4; --shadow: none; } }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; transition-duration: 0.01ms !important; } }
</style>
</head>
<body>
<header class="site-header"><nav class="nav" aria-label="Main navigation"><div class="brand">ClaudeCodeLab</div><ul class="nav-links"><li><a href="#guide">Guide</a></li><li><a href="#offer">Template</a></li></ul></nav></header>
<main class="page"><section class="hero"><h1>Media queries that survive real layouts</h1><p>Mobile-first CSS, cards com container queries, modo escuro e movimento reduzido.</p></section><div class="layout" id="guide"><article class="article"><h2>Readable article body</h2><p>The article stays readable on phones and gains a sidebar only when there is enough room.</p><div class="offer-wrap" id="offer"><section class="offer"><div class="offer-media" aria-hidden="true"></div><div><h2>Responsive review checklist</h2><p>Use this area for a download, newsletter or product CTA.</p><a class="button" href="#">Get the checklist</a></div></section></div></article><aside class="sidebar" aria-label="Related content"><section class="sidebar-card"><h2>Related</h2><p>Grid, Flexbox, accessibility and performance belong in the same review.</p></section></aside></div></main>
</body>
</html>
Prompts para Claude Code
Objetivo: CSS responsivo da página de artigo
Regras:
- Base mobile-first
- Media queries de viewport só para layout global
- Container queries para cards e CTAs reutilizáveis
- Não usar font-size apenas com vw; usar clamp()
- Respeitar prefers-color-scheme e prefers-reduced-motion
Verificação:
- Testar 375, 768, 1024 e 1440 px
- Testar dark mode e reduced motion no Playwright
- Apontar breakpoints duplicados ou desnecessários
Revise este diff como CSS responsivo.
Priorize overflow horizontal, texto ilegível, CTA/anúncio esmagado,
falta de container-type, violação de reduced-motion e excesso de breakpoints.
Retorne apenas linhas específicas e correções mínimas.
Teste com Playwright
import { test, expect } from "@playwright/test";
const fileUrl = "file:///absolute/path/to/responsive-demo.html";
for (const width of [375, 768, 1024, 1440]) {
test(`no horizontal overflow at ${width}px`, async ({ page }) => {
await page.setViewportSize({ width, height: 900 });
await page.goto(fileUrl);
const hasOverflow = await page.evaluate(() => document.documentElement.scrollWidth > document.documentElement.clientWidth);
await expect(hasOverflow).toBe(false);
await expect(page.locator(".offer")).toBeVisible();
});
}
test("dark mode keeps text readable", async ({ page }) => {
await page.emulateMedia({ colorScheme: "dark" });
await page.goto(fileUrl);
await expect(page.locator("body")).toHaveCSS("color", "rgb(238, 242, 247)");
});
test("reduced motion disables hover timing", async ({ page }) => {
await page.emulateMedia({ reducedMotion: "reduce" });
await page.goto(fileUrl);
const duration = await page.locator(".button").evaluate((el) => getComputedStyle(el).transitionDuration);
expect(duration).toBe("0.01ms");
});
flowchart TD
A["CSS mobile-first"] --> B["Media queries para layout"]
B --> C["Container queries para cards"]
C --> D["Preferências do usuário"]
D --> E["Screenshots e overflow no Playwright"]
E --> F["Prompt de revisão Claude Code"]
Erros e monetização
Evite empilhar max-width, usar viewport para componente reutilizável, definir fonte apenas com vw e ignorar reduced motion. Depois que Claude Code gerar CSS, valide textos traduzidos, CTAs reais, anúncios, modo escuro e larguras estreitas.
CSS responsivo protege receita: ofertas continuam visíveis sem prejudicar a leitura. Use um CTA discreto no meio do artigo para uma checklist gratuita e um CTA mais forte no final para templates ou consultoria. Veja o material gratuito, produtos ou treinamento.
No teste prático de Masa, a maior melhoria veio ao mover o card de CTA para container query. O mesmo card funcionou no corpo, na sidebar e nos relacionados sem novo breakpoint de viewport. Playwright confirmou ausência de overflow em 375px, texto legível no modo escuro e movimento reduzido aplicado.
PDF grátis: cheatsheet do Claude Code
Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.
Cuidamos dos seus dados e não enviamos spam.
Sobre o autor
Masa
Engenheiro focado em workflows práticos com Claude Code.
Artigos relacionados
Escada de segurança de permissões no Claude Code
Amplie de read-only para edições limitadas, comandos de prova e deploy checks sem perder controle.
Claude Code Small PR Proof Pack: pequenas mudanças fáceis de revisar
Um pacote de prova para PRs do Claude Code: diff, checks, URL pública, CTA e rollback.
Gate de revisão antes do commit com Claude Code
Revisão antes do commit com Claude Code: diff, build, URL pública, Gumroad, consultoria, testes e arquivos fora do escopo.