CSS Modules & Vanilla Extract mit Claude Code: Scoped Styles 2026

CSS Modules und Vanilla Extract lösen das globale CSS-Problem ohne Runtime-Overhead. Claude Code kennt beide Ansätze: Scoped CSS mit automatischen Klassen-Hashes, Theming mit CSS Custom Properties und Vanilla Extract als Zero-Runtime CSS-in-TypeScript.

CSS-Lösungen im Vergleich

AnsatzRuntime JSTypeScriptThemingIdeal für
CSS Modules0kbVia d.tsCSS VariablesKlassisches Scoping
Vanilla Extract0kbNativecreateTheme()Design Systems
Tailwind CSS0kbVia Plugintheme.extendUtility-first
styled-components~15kbGutThemeProviderComponent-first
Emotion~8kbGutThemeProviderFlexibel

CSS Modules: Scoped Styles ohne Config

CSS ModulesAutomatisch gescopte Klassennamen

/* Button.module.css */ /* Prompt: "Erstelle eine Button-Komponente mit CSS Modules" */ .button { display: inline-flex; align-items: center; gap: 8px; padding: 10px 20px; border-radius: 8px; font-weight: 600; cursor: pointer; border: none; transition: all 0.2s ease; } .primary { background: var(--color-primary); color: white; } .primary:hover { background: var(--color-primary-dark); transform: translateY(-1px); } .secondary { background: transparent; border: 2px solid var(--color-primary); color: var(--color-primary); } .small { padding: 6px 14px; font-size: 0.875rem; } .large { padding: 14px 28px; font-size: 1.1rem; } .loading { opacity: 0.7; cursor: not-allowed; } /* Composing (Vererbung): */ .dangerButton { composes: button; background: #ef4444; color: white; }
// Button.tsx — CSS Modules in React import styles from './Button.module.css'; // TypeScript erkennt styles.primary, styles.secondary etc.! type ButtonProps = { variant?: 'primary' | 'secondary' | 'danger'; size?: 'small' | 'medium' | 'large'; loading?: boolean; } & React.ButtonHTMLAttributes<HTMLButtonElement>; export function Button({ variant = 'primary', size = 'medium', loading, className, ...props }: ButtonProps) { const classes = [ styles.button, styles[variant], size !== 'medium' && styles[size], loading && styles.loading, className, ].filter(Boolean).join(' '); return <button className={classes} disabled={loading} {...props} />; } // Generiertes HTML: // <button class="Button_button__x3k9d Button_primary__2mn4f"> // Klassen sind automatisch unique — kein Konflikt möglich!

TypeScript-Typen für CSS Modules

# tsconfig.json — CSS Modules Typen aktivieren: { "compilerOptions": { "plugins": [{ "name": "typescript-plugin-css-modules" }] } } # Alternativ: global.d.ts (ohne Plugin): declare module '*.module.css' { const styles: { [className: string]: string }; export default styles; } # Beste Lösung: typed-css-modules für exakte Typen: npx typed-css-modules run 'src/**/*.module.css' # → Generiert Button.module.css.d.ts mit exakten Klassen-Namen

Vanilla Extract: CSS-in-TypeScript

Vanilla ExtractZero-Runtime CSS-in-TypeScript

// styles.css.ts — Vanilla Extract // Prompt: "Design System mit Vanilla Extract und Token-basiertem Theming" import { style, styleVariants, createVar } from '@vanilla-extract/css'; // CSS Custom Property als Variable: export const colorPrimary = createVar(); // Base Style: export const button = style({ display: 'inline-flex', alignItems: 'center', padding: '10px 20px', borderRadius: '8px', fontWeight: 600, cursor: 'pointer', border: 'none', transition: 'all 0.2s ease', }); // Varianten automatisch generieren: export const buttonVariant = styleVariants({ primary: { background: '#6366f1', color: 'white', ':hover': { background: '#4f46e5' }, }, secondary: { background: 'transparent', border: '2px solid #6366f1', color: '#6366f1', }, danger: { background: '#ef4444', color: 'white', }, });

Vanilla Extract Theming: createTheme

ThemingLight/Dark Theme mit Type Safety

// theme.css.ts import { createTheme, createThemeContract } from '@vanilla-extract/css'; // Contract definiert die "Shape" — beide Themes MÜSSEN alle Keys implementieren: export const themeVars = createThemeContract({ colors: { background: null, foreground: null, primary: null, primaryForeground: null, muted: null, border: null, }, space: { xs: null, sm: null, md: null, lg: null, xl: null }, fontSizes: { sm: null, base: null, lg: null, xl: null }, radii: { sm: null, md: null, lg: null, full: null }, }); // Light Theme: export const lightTheme = createTheme(themeVars, { colors: { background: '#ffffff', foreground: '#0f172a', primary: '#6366f1', primaryForeground: '#ffffff', muted: '#f1f5f9', border: '#e2e8f0', }, space: { xs: '4px', sm: '8px', md: '16px', lg: '24px', xl: '32px' }, fontSizes: { sm: '0.875rem', base: '1rem', lg: '1.125rem', xl: '1.25rem' }, radii: { sm: '4px', md: '8px', lg: '12px', full: '9999px' }, }); // Dark Theme — TypeScript zwingt zur Vollständigkeit! export const darkTheme = createTheme(themeVars, { colors: { background: '#0f172a', foreground: '#f8fafc', primary: '#818cf8', primaryForeground: '#1e1b4b', muted: '#1e293b', border: '#334155', }, space: { xs: '4px', sm: '8px', md: '16px', lg: '24px', xl: '32px' }, fontSizes: { sm: '0.875rem', base: '1rem', lg: '1.125rem', xl: '1.25rem' }, radii: { sm: '4px', md: '8px', lg: '12px', full: '9999px' }, }); // Nutzung: // <div className={isDark ? darkTheme : lightTheme}> → CSS Variables gesetzt!
Vanilla Extract Build-Step: Styles werden zur Build-Zeit zu normalem CSS kompiliert — kein JavaScript zur Laufzeit. Bundle-Size-Auswirkung: 0 Bytes. Perfect für Server Components und statische Sites.

Styling-Modul im Kurs

Im Claude Code Mastery Kurs: vollständiges Styling-Modul mit CSS Modules, Vanilla Extract Design Systems, Sprinkles Utility API und Tailwind CSS — inkl. Migration von styled-components und Theme-Switching.

14 Tage kostenlos testen →