Responsive Design mit Claude Code: Mobile-first CSS und Playwright
Responsive UI mit Claude Code: mobile-first CSS, clamp, Grids, Bilder, Navigation, Tabellen und Playwright.
Vor dem CSS die Regeln festlegen
Responsive Design bedeutet nicht, eine Desktop-Seite so lange zu verkleinern, bis sie auf ein Smartphone passt. Eine gute Seite berucksichtigt Bildschirmbreite, Touch-Ziele, Bildgewicht, Navigationsprioritat, lesbare Tabellen, Anzeigen und Conversion-CTAs. Wenn du Claude Code nur “mach das mobilfreundlich” sagst, kann eine einzelne Ansicht gut aussehen, wahrend horizontales Scrollen, fixe Kartenbreiten, zu schwere Hero-Bilder, enge Navigation oder ein zu tief liegender Kaufbutton bleiben.
Gib Claude Code deshalb einen kurzen, prufbaren Vertrag. Mobile-first CSS bedeutet: die schmale Ansicht ist die Basis, breite Ansichten erganzen nur. clamp() ist eine CSS-Funktion fur Mindestwert, bevorzugten Wert und Maximalwert. Container Queries lassen Komponenten auf die Breite ihres Containers reagieren, nicht nur auf den gesamten Viewport. Diese Begriffe sind einfach, aber sie verhindern vage Auftrage und machen den Diff leichter reviewbar.
Als offizielle Quellen nutze MDN: Responsive design, @container, clamp() und responsive images. Fur die Prufung eignen sich Playwright Screenshots und Visual comparisons. Die offiziellen Seiten Claude Code overview und How Claude Code works beschreiben Claude Code als Werkzeug, das Code liest, Dateien andert, Kommandos ausfuhrt und Ergebnisse verifiziert. Genau so solltest du es hier einsetzen.
Passende Grundlagen findest du auch in Claude Code Design Systems, Claude Code Accessibility und Claude Code Playwright Testing.
Implementierungsplan
Responsive Arbeit scheitert oft, wenn CSS am Ende als Patch angehangt wird. Bitte Claude Code zuerst die bestehende Seite zu lesen, die Breiten zu finden, an denen Komponenten brechen, und CSS, Bilder sowie Tests zusammen anzupassen.
flowchart LR
A["Bestehende Seite lesen"] --> B["Mobile-first Basis-CSS"]
B --> C["Fluid Grid und clamp()"]
C --> D["Komponenten mit Container Query"]
D --> E["Responsive Bilder und Tabellen"]
E --> F["Playwright Screenshots"]
Dieser Prompt ist konkret genug:
Mache die bestehende Seite /responsive-demo responsiv.
Anforderungen:
- Verwende mobile-first CSS.
- Kein horizontaler Overflow bei 320px, 390px, 768px, 1024px und 1440px.
- Navigation, Karten, Preistabelle, Artikel-CTA und Footer durfen sich nicht uberlappen.
- Inhaltsbilder brauchen width/height, srcset, sizes, loading und sinnvolles alt.
- Bevorzuge CSS Grid, clamp() und @container vor JavaScript-Breitenlogik.
- Nach der Anderung Playwright Screenshots und eine Overflow-Assertion ausfuhren.
Nicht tun:
- Bestehende URLs, Conversion-CTA-Links oder zugangliche Heading-Reihenfolge nicht verandern.
- Keine grossen festen min-width-Werte hinzufugen, die Seitenscrollen erzwingen.
Damit sind Ziel, Grenzen und Beweis klar. Ein Diff, der nur auf Desktop gut aussieht, fallt sofort auf.
Kopierbares HTML
Das Beispiel enthalt Navigation, Hero, Bild, Karten, Seitenpanel und Vergleichstabelle. Ersetze nur die Bildpfade durch eigene Assets und nutze das CSS der nachsten Sektion.
<!doctype html>
<html lang="de">
<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="Hauptnavigation">
<a href="/de/blog/">Artikel</a>
<a href="/en/products/">Produkte</a>
<a href="/en/training/">Beratung</a>
</nav>
</header>
<main class="page-shell">
<section class="hero">
<div>
<p class="eyebrow">Responsive Design</p>
<h1>Erst den kleinen Bildschirm entwerfen, dann das Layout wachsen lassen</h1>
<p class="lead">
Implementiere mobile-first CSS, fluide Grids, responsive Bilder und Playwright Checks als einen Workflow.
</p>
<a class="primary-cta" href="/en/products/">Prompt-Vorlagen ansehen</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="Smartphone und Laptop zeigen dieselbe responsive Seite"
width="1280"
height="900"
loading="eager"
decoding="async"
/>
</picture>
</section>
<div class="layout-grid">
<aside class="side-panel" aria-label="Viewport Checkliste">
<h2>Zu prufende Breiten</h2>
<ul>
<li>320px: kleines Smartphone</li>
<li>390px: typisches Smartphone</li>
<li>768px: Tablet</li>
<li>1024px und mehr: Desktop</li>
</ul>
</aside>
<section class="cards" aria-label="Verbesserungskarten">
<article class="card featured">
<img src="/images/card-layout.jpg" alt="" width="720" height="480" loading="lazy" />
<div class="card-body">
<h2>Karten reagieren auf den Container</h2>
<p>Wiederverwendbare Komponenten sollen ihre Dichte nach dem verfugbaren Platz anpassen.</p>
</div>
</article>
<article class="card">
<div class="card-body">
<h2>Navigation darf umbrechen</h2>
<p>Desktop-Links nicht in eine einzige mobile Zeile pressen, sondern Touch-Flachen erhalten.</p>
</div>
</article>
<article class="card">
<div class="card-body">
<h2>Tabellen behalten Bedeutung</h2>
<p>Auf schmalen Screens werden Zeilen zu Karten, `data-label` zeigt den Spaltennamen.</p>
</div>
</article>
</section>
</div>
<section class="comparison">
<h2>Planvergleich</h2>
<table class="responsive-table">
<thead>
<tr>
<th scope="col">Element</th>
<th scope="col">Solo</th>
<th scope="col">Team</th>
</tr>
</thead>
<tbody>
<tr>
<td data-label="Element">Ziel</td>
<td data-label="Solo">Lernen und kleine Verbesserungen</td>
<td data-label="Team">Einheitliche Review-Standards</td>
</tr>
<tr>
<td data-label="Element">Nachweis</td>
<td data-label="Solo">Lokales Playwright</td>
<td data-label="Team">CI-Screenshots</td>
</tr>
</tbody>
</table>
</section>
</main>
</body>
</html>
Mobile-first CSS, Fluid Grid und clamp
Das CSS beginnt mit der schmalen Ansicht. Breitere Layouts kommen danach. Karten nutzen repeat(auto-fit, minmax(...)), Typografie und Abstand nutzen clamp(), und die Featured Card andert sich nur, wenn ihr eigener Container breit genug ist.
* {
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);
}
}
Entscheidend ist, dass grosse fixe Breiten verschwinden. width: min(100% - 2rem, 72rem) lasst auf kleinen Screens Luft und begrenzt grosse Screens. minmax(min(100%, 18rem), 1fr) verhindert, dass eine Karte ihren Container sprengt.
Muster fur Bilder, Navigation, Karten und Tabellen
Gib Claude Code Kriterien pro Komponente.
| Komponente | Haufiger Fehler | Gewunschte Korrektur |
|---|---|---|
| Navigation | Desktop-Links werden in eine mobile Zeile gepresst | Umbruch erlauben, Touch-Ziele und aria-label behalten |
| Karten | width: 320px oder grosses min-width erzeugt Overflow | auto-fit, minmax() und Container Queries verwenden |
| Bilder | Smartphones laden dasselbe grosse JPEG | srcset, sizes, width, height, loading und alt erganzen |
| Tabellen | Spalten werden unlesbar | Wrapper-Scroll oder Zeilenkarten mit data-label wahlen |
| CTA | Umsatzlink wird verdeckt | Ersten mobilen Scroll und Artikelende prufen |
Nicht jede kleine Navigation braucht ein Hamburger-Menu. Bei drei Links ist Umbruch oft klarer. Auch Tabellen brauchen unterschiedliche Losungen: Preisvergleiche profitieren von horizontaler Sicht, Ticketlisten von Zeilenkarten.
Use Cases zum Testen
Erster Use Case: SaaS-Dashboard. Sidebar, Filter, KPI-Karten, Diagramme und Tabellen treffen zusammen. Auf Mobile sollten wichtigste KPIs zuerst erscheinen, Filter einklappen und Detailzeilen als Karten lesbar bleiben.
Zweiter Use Case: Blog oder Medienseite. Textbreite, Inhaltsverzeichnis, Anzeigen, verwandte Artikel und PDF-CTA konkurrieren. Prufe Zeilenlange, Bildgewicht, Codeblock-Overflow und CTA-Sichtbarkeit.
Dritter Use Case: E-Commerce- oder Kurs-Landingpage. Produktkarten, Preisvergleich, Kaufbutton und FAQ beeinflussen Umsatz direkt. Wenn Preis oder Kaufbutton auf Mobile zu weit nach unten rutschen, leidet Conversion.
Vierter Use Case: internes Admin-UI. Tagliche Nutzer brauchen Suche, Filter, Tastaturbedienung und lesbare Tabellen. Responsive Design darf ihren Arbeitsablauf nicht umwerfen.
Mit Playwright prufen
Beende die Aufgabe nicht nach einem manuellen Blick. Playwright kann mehrere Breiten testen, wichtige Elemente sichtbar machen, horizontalen Overflow erkennen und Screenshots speichern.
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: "Hauptnavigation" })).toBeVisible();
await expect(page.getByRole("link", { name: "Prompt-Vorlagen ansehen" })).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,
});
});
}
Der erste Lauf erzeugt Referenzbilder. Aktualisiere sie mit npx playwright test --update-snapshots nur bei beabsichtigten Anderungen. Screenshots hangen von OS, Font-Rendering, GPU und Headless-Modus ab, also nutze fur Vergleich und Baseline dieselbe CI-Umgebung.
Typische Fallen
Die grosste Falle ist Desktop-first CSS mit mobilen Overrides. Anfangs ist das schnell, spater wird die Cascade unlesbar. Lass Claude Code die schmale Ansicht in die Basisregeln verschieben und breite Layouts danach erganzen.
Zweite Falle: fehlendes <meta name="viewport">. Ohne dieses Tag kann ein mobiler Browser mit virtueller Desktop-Breite rendern.
Dritte Falle: versteckte fixe Breiten in Karten, Tabellen, Bildern oder Embeds. min-width: 960px fallt auf Desktop nicht auf, bricht aber Telefone. Wenn eine Tabelle scrollen muss, gib nur dem Wrapper overflow-x: auto.
Vierte Falle: srcset ohne sizes. Der Browser braucht Kandidaten und eine Angabe zur gerenderten Breite. Prufe srcset, sizes, width, height und alt zusammen.
Funfte Falle: nur Screenshots vertrauen. Anzeigen, Daten, Animationen und Widgets erzeugen Rauschen. Kombiniere Screenshots mit DOM-Assertions fur Overflow, sichtbare CTA und Navigation-Landmarks.
Umsatzpfad einbeziehen
Responsive Design muss das Geschaftsziel schutzen. Auf ClaudeCodeLab sollen mobile Leser PDF, Gumroad-Produkte und Beratung finden. Fur wiederverwendbare Workflows siehe Claude Code products. Fur echte Team-Screens mit Review-Regeln und Playwright-Proof siehe Claude Code training.
Nimm den Conversion-Pfad in den Brief fur Claude Code auf. Eine saubere Seite, die Kaufbutton oder Kontaktlink versteckt, ist nicht fertig.
Fazit
Der praktische Ablauf lautet: mobile-first Vertrag definieren, fluide Grids bauen, clamp() fur Typografie und Abstand nutzen, Container Queries fur Komponenten einsetzen, Bilder bewusst behandeln, Navigation und Tabellen an die Aufgabe anpassen und mit Playwright verifizieren.
Ich habe das Muster aus diesem Artikel bei 320px, 390px, 768px und 1440px getestet. Die Navigation brach ohne Overflow um, Karten wurden auf Mobile einspaltig, die Tabelle war als Zeilenkarten lesbar und die Playwright-Overflow-Assertion bestand. Masas praktische Erkenntnis: Claude Code hilft am meisten, wenn es erst implementiert und dann feste Breiten, Bildhinweise, CTA-Position, Tabellenverhalten und Screenshot-Unterschiede kritisch reviewt.
Kostenloses PDF: Claude-Code-Cheatsheet
E-Mail eintragen und eine Seite mit Befehlen, Review-Gewohnheiten und sicheren Workflows herunterladen.
Wir schützen Ihre Daten und senden keinen Spam.
Über den Autor
Masa
Engineer für praktische Claude-Code-Workflows und Team-Einführung.
Ähnliche Artikel
Claude Code Permission Safety Ladder: Zugriff kontrolliert erweitern
Von read-only zu begrenzten Änderungen, Prüfbefehlen und Deploy-Checks mit klarer Kontrolle.
Claude Code Small PR Proof Pack: kleine Änderungen reviewbar machen
Ein Proof Pack für Claude-Code-PRs: Diff, Checks, öffentliche URL, CTA-Pfad und Rollback.
Claude-Code-Review-Gate vor dem Commit
Vor dem Commit mit Claude Code prüfen: Diff, Build, öffentliche URL, Gumroad-Links, Beratung-CTA, fehlende Tests und fremde Dateien.