Tips & Tricks (Atualizado: 02/06/2026)

Design responsivo com Claude Code: CSS mobile-first e Playwright

Design responsivo com Claude Code: CSS mobile-first, clamp, grids, imagens, navegacao, tabelas e Playwright.

Design responsivo com Claude Code: CSS mobile-first e Playwright

Defina criterios antes de pedir a mudanca

Design responsivo nao e apenas encolher uma pagina desktop ate caber no celular. Uma pagina pronta para publicar precisa considerar largura de tela, area de toque, peso das imagens, prioridade da navegacao, legibilidade de tabelas, anuncios e CTAs de conversao. Se voce pedir ao Claude Code apenas “deixe mobile friendly”, ele pode ajustar uma largura especifica e deixar problemas escondidos: scroll horizontal, cards com largura fixa, imagem hero pesada, menu apertado ou botao de compra perdido no fim da pagina.

O caminho mais seguro e entregar um contrato curto e verificavel. CSS mobile-first significa que a tela pequena e a base, e telas maiores recebem melhorias. clamp() e uma funcao CSS que define valor minimo, preferido e maximo. Container query permite que um componente responda ao tamanho do seu proprio contenedor, nao apenas ao viewport. Com isso no prompt, o diff gerado pelo Claude Code fica mais facil de revisar.

Use como base oficial a MDN: Responsive design, @container, clamp() e responsive images. Para validar, use Playwright Screenshots e Visual comparisons. A documentacao atual de Claude Code overview e How Claude Code works mostra Claude Code como uma ferramenta que le o repositorio, edita arquivos, executa comandos e verifica resultado. E assim que ele deve ser usado aqui.

Para completar a base, leia tambem design system com Claude Code, acessibilidade com Claude Code e testes Playwright com Claude Code.

Mapa de implementacao

Trabalho responsivo costuma falhar quando CSS vira um remendo final. Peça ao Claude Code para ler a pagina existente, descobrir em quais larguras cada componente quebra, atualizar CSS e imagens juntos e adicionar verificacao visual.

flowchart LR
  A["Ler pagina existente"] --> B["CSS base mobile-first"]
  B --> C["Fluid grid e clamp()"]
  C --> D["Componentes com container query"]
  D --> E["Imagens e tabelas responsivas"]
  E --> F["Screenshots Playwright"]

Use um prompt assim:

Torne a pagina existente /responsive-demo responsiva.

Requisitos:
- Usar CSS mobile-first.
- Evitar scroll horizontal em 320px, 390px, 768px, 1024px e 1440px.
- Navegacao, cards, tabela de precos, CTA do artigo e footer nao podem se sobrepor.
- Imagens de conteudo devem ter width/height, srcset, sizes, loading e alt util.
- Priorizar CSS Grid, clamp() e @container antes de adicionar JavaScript para medir largura.
- Depois da mudanca, executar screenshots e assertion de overflow com Playwright.

Nao fazer:
- Nao alterar URLs existentes, links de conversao nem hierarquia acessivel de headings.
- Nao adicionar grandes min-width fixos que causem scroll horizontal na pagina inteira.

Esse formato deixa objetivo, limites e prova no mesmo lugar. Se a solucao so funciona no desktop, ela nao passa.

HTML pronto para copiar

O exemplo abaixo inclui navegacao, hero, imagem, cards, painel lateral e tabela comparativa. Troque apenas as rotas das imagens pelas do seu projeto e use o CSS da proxima secao.

<!doctype html>
<html lang="pt-BR">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Responsive Demo</title>
    <link rel="stylesheet" href="./responsive-demo.css" />
  </head>
  <body>
    <header class="site-nav">
      <a class="brand" href="/">ClaudeCodeLab</a>
      <nav class="nav-links" aria-label="Navegacao principal">
        <a href="/pt/blog/">Artigos</a>
        <a href="/en/products/">Produtos</a>
        <a href="/en/training/">Consultoria</a>
      </nav>
    </header>

    <main class="page-shell">
      <section class="hero">
        <div>
          <p class="eyebrow">Responsive Design</p>
          <h1>Desenhe primeiro a tela pequena e deixe o layout crescer</h1>
          <p class="lead">
            Implemente CSS mobile-first, grids fluidos, imagens responsivas e checks Playwright em um unico fluxo.
          </p>
          <a class="primary-cta" href="/en/products/">Ver templates de prompts</a>
        </div>
        <picture class="hero-media">
          <source
            type="image/avif"
            srcset="/images/responsive-demo-640.avif 640w, /images/responsive-demo-1280.avif 1280w"
            sizes="(width < 768px) 92vw, 40vw"
          />
          <img
            src="/images/responsive-demo-1280.jpg"
            alt="Celular e notebook mostrando a mesma pagina responsiva"
            width="1280"
            height="900"
            loading="eager"
            decoding="async"
          />
        </picture>
      </section>

      <div class="layout-grid">
        <aside class="side-panel" aria-label="Checklist de viewport">
          <h2>Larguras para verificar</h2>
          <ul>
            <li>320px: celular pequeno</li>
            <li>390px: celular comum</li>
            <li>768px: tablet</li>
            <li>1024px ou mais: desktop</li>
          </ul>
        </aside>

        <section class="cards" aria-label="Cards de melhoria">
          <article class="card featured">
            <img src="/images/card-layout.jpg" alt="" width="720" height="480" loading="lazy" />
            <div class="card-body">
              <h2>Cards respondem ao contenedor</h2>
              <p>Um componente reutilizavel deve ajustar densidade conforme o espaco onde esta inserido.</p>
            </div>
          </article>
          <article class="card">
            <div class="card-body">
              <h2>Navegacao pode quebrar linha</h2>
              <p>Nao pressione todos os links desktop em uma unica linha no mobile.</p>
            </div>
          </article>
          <article class="card">
            <div class="card-body">
              <h2>A tabela preserva significado</h2>
              <p>Em telas estreitas, linhas viram cards e `data-label` mostra o nome da coluna.</p>
            </div>
          </article>
        </section>
      </div>

      <section class="comparison">
        <h2>Comparacao de planos</h2>
        <table class="responsive-table">
          <thead>
            <tr>
              <th scope="col">Item</th>
              <th scope="col">Individual</th>
              <th scope="col">Equipe</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td data-label="Item">Objetivo</td>
              <td data-label="Individual">Aprendizado e pequenas melhorias</td>
              <td data-label="Equipe">Padroes de review consistentes</td>
            </tr>
            <tr>
              <td data-label="Item">Prova</td>
              <td data-label="Individual">Playwright local</td>
              <td data-label="Equipe">Screenshots em CI</td>
            </tr>
          </tbody>
        </table>
      </section>
    </main>
  </body>
</html>

CSS mobile-first, grid fluido e clamp

O CSS comeca pela tela estreita. Telas maiores adicionam colunas depois. Cards usam repeat(auto-fit, minmax(...)), fontes e espacamentos usam clamp(), e o card em destaque muda apenas quando o proprio contenedor tem largura suficiente.

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  color: #172033;
  background: #f7f8fb;
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

img {
  display: block;
  max-width: 100%;
  height: auto;
}

.site-nav,
.page-shell {
  width: min(100% - 2rem, 72rem);
  margin-inline: auto;
}

.site-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding-block: 1rem;
}

.brand,
.nav-links a,
.primary-cta {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

.nav-links {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.nav-links a {
  padding-inline: 0.75rem;
  color: inherit;
  text-decoration: none;
}

.page-shell {
  padding-block: clamp(1rem, 4vw, 3rem);
}

.hero {
  display: grid;
  gap: clamp(1rem, 4vw, 2.5rem);
  align-items: center;
}

.hero h1 {
  max-width: 11ch;
  margin: 0;
  font-size: clamp(2.25rem, 10vw, 5rem);
  line-height: 1.02;
}

.lead {
  max-width: 62ch;
  font-size: clamp(1rem, 2vw, 1.25rem);
  line-height: 1.8;
}

.primary-cta {
  width: fit-content;
  border-radius: 0.5rem;
  padding: 0.75rem 1rem;
  background: #172033;
  color: white;
  text-decoration: none;
  font-weight: 700;
}

.layout-grid {
  display: grid;
  gap: clamp(1rem, 3vw, 2rem);
  margin-block-start: 2rem;
}

.cards {
  container: cards / inline-size;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
  gap: 1rem;
}

.side-panel,
.card,
.comparison {
  background: white;
  border: 1px solid #dbe3ef;
  border-radius: 0.75rem;
}

.card {
  overflow: hidden;
}

.card-body,
.side-panel,
.comparison {
  padding: 1rem;
}

@container cards (width >= 42rem) {
  .card.featured {
    grid-column: span 2;
    display: grid;
    grid-template-columns: minmax(14rem, 0.8fr) 1fr;
  }

  .card.featured img {
    height: 100%;
    object-fit: cover;
  }
}

.comparison {
  margin-block-start: 2rem;
  overflow-x: auto;
}

.responsive-table {
  width: 100%;
  border-collapse: collapse;
}

.responsive-table th,
.responsive-table td {
  padding: 0.875rem;
  border-block-end: 1px solid #dbe3ef;
  text-align: left;
}

@media (width < 48rem) {
  .responsive-table thead {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
  }

  .responsive-table,
  .responsive-table tbody,
  .responsive-table tr,
  .responsive-table td {
    display: block;
    width: 100%;
  }

  .responsive-table tr {
    border: 1px solid #dbe3ef;
    border-radius: 0.5rem;
    margin-block: 0.75rem;
    overflow: hidden;
  }

  .responsive-table td {
    display: grid;
    grid-template-columns: minmax(7rem, 40%) 1fr;
    gap: 1rem;
  }

  .responsive-table td::before {
    content: attr(data-label);
    font-weight: 700;
    color: #526071;
  }
}

@media (width >= 64rem) {
  .hero {
    grid-template-columns: minmax(0, 1.1fr) minmax(18rem, 0.9fr);
  }

  .layout-grid {
    grid-template-columns: 16rem minmax(0, 1fr);
  }
}

O ponto principal e remover grandes larguras fixas. width: min(100% - 2rem, 72rem) deixa margem em telas pequenas e limita a leitura em telas grandes. minmax(min(100%, 18rem), 1fr) impede que a largura minima do card estoure o contenedor.

Padroes para imagens, navegacao, cards e tabelas

Entregue regras por componente ao Claude Code.

ComponenteFalha comumCorrecao a pedir
NavegacaoLinks desktop comprimidos em uma linha mobilePermitir quebra, manter area de toque e aria-label
Cardswidth: 320px ou min-width grande causa overflowUsar auto-fit, minmax() e container queries
ImagensCelular baixa o mesmo JPEG grandeAdicionar srcset, sizes, width, height, loading e alt
TabelasColunas ficam ilegiveisEscolher scroll no wrapper ou cards por linha com data-label
CTALink de receita fica escondidoVerificar primeiro scroll mobile e fim do artigo

Nem todo menu pequeno precisa virar hamburger. Com tres links, quebra de linha pode ser mais clara. Tabelas tambem variam: matriz de precos pode precisar de comparacao horizontal, enquanto lista de tickets costuma funcionar melhor como cards.

Casos de uso para testar

O primeiro caso e um dashboard SaaS. Sidebar, filtros, cards KPI, graficos e tabela aparecem juntos. No mobile, mostre KPIs principais primeiro, recolha filtros secundarios e transforme linhas detalhadas em cards.

O segundo e um blog ou site de conteudo. Largura do texto, sumario, anuncios, posts relacionados e CTA de PDF gratuito competem por espaco. Verifique linha de leitura, imagens leves, blocos de codigo sem overflow e CTA visivel.

O terceiro e uma landing de ecommerce ou curso. Cards de produto, comparacao de preco, botao de compra e FAQ afetam receita. Se preco ou compra ficam muito abaixo no mobile, a conversao sofre.

O quarto e uma tela interna de administracao. Usuarios diarios querem busca, filtros, teclado e tabelas legiveis. A melhoria responsiva deve preservar a ordem de trabalho.

Verifique com Playwright

Nao encerre so porque a pagina parece boa em um navegador. Playwright testa larguras representativas, confirma elementos visiveis, detecta overflow horizontal e salva screenshots.

import { expect, test } from "@playwright/test";

const baseUrl = process.env.PLAYWRIGHT_BASE_URL ?? "http://127.0.0.1:3000";

const viewports = [
  { name: "mobile-320", width: 320, height: 740 },
  { name: "mobile-390", width: 390, height: 844 },
  { name: "tablet-768", width: 768, height: 1024 },
  { name: "desktop-1440", width: 1440, height: 1000 },
];

for (const viewport of viewports) {
  test(`responsive demo has no horizontal overflow at ${viewport.name}`, async ({ page }) => {
    await page.setViewportSize({ width: viewport.width, height: viewport.height });
    await page.goto(`${baseUrl}/responsive-demo`);

    await expect(page.getByRole("navigation", { name: "Navegacao principal" })).toBeVisible();
    await expect(page.getByRole("link", { name: "Ver templates de prompts" })).toBeVisible();

    const hasHorizontalOverflow = await page.evaluate(() => {
      return document.documentElement.scrollWidth > document.documentElement.clientWidth;
    });

    expect(hasHorizontalOverflow).toBe(false);
    await expect(page).toHaveScreenshot(`responsive-${viewport.name}.png`, {
      fullPage: true,
      maxDiffPixels: 300,
    });
  });
}

A primeira execucao cria screenshots base. Atualize com npx playwright test --update-snapshots apenas quando a mudanca visual for intencional. Para reduzir ruido, compare no mesmo ambiente de CI.

Armadilhas comuns

A maior armadilha e CSS desktop-first com overrides mobile acumulados. No inicio parece rapido, mas a cascade vira um problema. Peça ao Claude Code para mover a tela pequena para as regras base e adicionar layouts largos depois.

Outra armadilha e esquecer <meta name="viewport">. Sem ele, o navegador mobile pode renderizar com largura virtual de desktop.

Tambem existem larguras fixas escondidas em cards, tabelas, imagens ou embeds. min-width: 960px passa despercebido em desktop e quebra celulares. Se a tabela precisa scrollar, aplique overflow-x: auto no wrapper dela.

O quarto erro e usar srcset sem sizes. O navegador precisa dos candidatos e da dica de largura renderizada. Revise srcset, sizes, width, height e alt em conjunto.

O quinto erro e confiar so em screenshots. Anuncios, datas, animacoes e widgets externos geram ruido. Combine screenshots com assertions de DOM para overflow, CTA visivel e landmarks de navegacao.

Inclua o caminho de receita

Design responsivo tambem deve proteger o objetivo de negocio. No ClaudeCodeLab, o leitor mobile precisa encontrar PDF gratuito, produtos Gumroad e consultoria. Para fluxos reutilizaveis, veja Claude Code products. Para trabalhar telas reais com regras de review e Playwright, veja Claude Code training.

Coloque o caminho de conversao no brief. Uma pagina limpa que esconde o botao de compra ou o link de contato nao esta pronta.

Resumo

O fluxo pratico e: definir o contrato mobile-first, construir grids fluidos, usar clamp() para tipografia e espacamento, aplicar container queries em componentes reutilizaveis, tratar imagens com cuidado, adaptar navegacao e tabelas a tarefa do leitor e verificar com Playwright.

Testei o padrao deste artigo em 320px, 390px, 768px e 1440px. A navegacao quebrou linha sem overflow, os cards ficaram em uma coluna no mobile, a tabela virou cards por linha e a assertion de overflow do Playwright passou. A conclusao pratica de Masa: Claude Code ajuda mais quando implementa e depois revisa larguras fixas, hints de imagem, posicao do CTA, comportamento de tabelas e diferencas de screenshot.

#Claude Code #responsive #CSS #mobile #Playwright
Grátis

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.

Masa

Sobre o autor

Masa

Engenheiro focado em workflows práticos com Claude Code.