Communitygithub.com

Frontend Designer

Erstelle barrierefreie, responsive und performante Frontend-Komponenten mit Best Practices für Designsysteme, modernem CSS und framework-unabhängigen Mustern.

Was ist Frontend Designer?

Dieser Skill unterstützt Frontend-Designer und -Entwickler beim Erstellen schöner, zugänglicher und leistungsstarker Benutzeroberflächen mit modernen Best Practices. Er umfasst Komponentendesign und -entwicklung, Designsysteme, Responsive Design, Barrierefreiheit (WCAG 2.1), modernes CSS, Leistungsoptimierung und Framework-Muster. Der Skill bietet konkrete, wiederverwendbare Komponentenmuster (wie Buttons, Cards und Formulareingaben) mit vollständigen TypeScript- und CSS-Implementierungen, die auf einem durchgängigen Token-basierten Designsystem aufbauen. Er enthält praktische Anleitungen zu Design-Tokens, responsiven Layouts, Barrierefreiheitsmustern und Leistungsoptimierungstechniken wie Critical CSS und Lazy Loading. Ideal für Entwickler, die konsistente, wartbare und inklusive Benutzeroberflächen in React, Vue oder Svelte umsetzen möchten – ohne an ein bestimmtes Framework gebunden zu sein.

Funktioniert mit✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/Samueladewole/claude-skills/tree/HEAD/frontend-designer

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Was macht Frontend Designer?

Ein umfassender Skill für Frontend-Designer und -Entwickler, um schöne, barrierefreie und performante Benutzeroberflächen mit modernen Best Practices zu erstellen.

Was dieser Skill macht

Hilft Frontend-Designern/-Entwicklern bei:

  • Komponentendesign & -entwicklung – Erstelle wiederverwendbare, barrierefreie Komponenten
  • Designsysteme – Implementiere Tokens, Muster und Dokumentation
  • Responsive Design – Mobile-First, flüssige Layouts
  • Barrierefreiheit (WCAG 2.1) – Inklusive Designmuster
  • Modernes CSS – Flexbox, Grid, benutzerdefinierte Eigenschaften
  • Leistungsoptimierung – Schnelle, effiziente Frontends
  • Framework-Muster – Best Practices für React, Vue, Svelte
  • Design-to-Code – Workflows von Figma bis zur Produktion

Warum dieser Skill wichtig ist

Ohne systematischen Ansatz:

  • Inkonsistente Komponentenimplementierungen
  • Barrierefreiheitsprobleme
  • Schlechtes responsives Verhalten
  • Doppelter Code und Styles
  • Schwer zu warten
  • Leistungsprobleme

Mit diesem Skill:

  • Konsistente, wiederverwendbare Komponenten
  • WCAG AA konform standardmäßig
  • Mobile-First responsives Design
  • Designsystem-konform
  • Wartbare Codebasis
  • Schnelle, optimierte Auslieferung

Kernprinzipien

1. Barrierefreiheit zuerst

  • WCAG 2.1 AA als Minimum
  • Semantisches HTML
  • Tastaturnavigation
  • Screenreader-Unterstützung
  • Fokusverwaltung
  • Farbkontrast

2. Mobile-First Responsive

  • Beginne mit mobile (320px)
  • Progressive Verbesserung
  • Flüssige Typografie
  • Flexible Layouts
  • Touch-freundliche Ziele

3. Leistung standardmäßig

  • Minimales CSS/JS
  • Lazy Loading
  • Optimierte Bilder
  • Kritisches CSS
  • Tree Shaking

4. Komponentengetrieben

  • Atomare Design-Methodik
  • Wiederverwendbare Komponenten
  • Props-basierte Anpassung
  • Komposition vor Vererbung

5. Designsystem-konform

  • Design-Tokens
  • Konsistente Abstände
  • Typografie-Skala
  • Farbpalette
  • Komponentenbibliothek

Komponentenmuster

Button-Komponente

Barrierefreies, flexibles Button-Muster:

// React Beispiel
interface ButtonProps {
  variant?: 'primary' | 'secondary' | 'ghost';
  size?: 'sm' | 'md' | 'lg';
  disabled?: boolean;
  loading?: boolean;
  children: React.ReactNode;
  onClick?: () => void;
}

export const Button: React.FC<ButtonProps> = ({
  variant = 'primary',
  size = 'md',
  disabled = false,
  loading = false,
  children,
  onClick,
  ...props
}) => {
  return (
    <button
      className={`btn btn--${variant} btn--${size}`}
      disabled={disabled || loading}
      onClick={onClick}
      aria-busy={loading}
      {...props}
    >
      {loading ? <Spinner /> : children}
    </button>
  );
};

CSS (mit Design-Tokens):

.btn {
  /* Basis-Stile */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);

  font-family: var(--font-sans);
  font-weight: 600;
  text-decoration: none;

  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;

  transition: all 0.2s ease;

  /* Barrierefreiheit */
  min-height: 44px; /* WCAG touch target */

  &:focus-visible {
    outline: 2px solid var(--color-focus);
    outline-offset: 2px;
  }

  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
}

/* Varianten */
.btn--primary {
  background: var(--color-primary);
  color: var(--color-on-primary);

  &:hover:not(:disabled) {
    background: var(--color-primary-hover);
  }
}

.btn--secondary {
  background: var(--color-secondary);
  color: var(--color-on-secondary);
}

.btn--ghost {
  background: transparent;
  color: var(--color-primary);
  border: 1px solid currentColor;
}

/* Größen */
.btn--sm {
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
}

.btn--md {
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-base);
}

.btn--lg {
  padding: var(--space-4) var(--space-6);
  font-size: var(--text-lg);
}

Card-Komponente

Flexible, barrierefreie Card:

interface CardProps {
  variant?: 'elevated' | 'outlined' | 'filled';
  padding?: 'none' | 'sm' | 'md' | 'lg';
  interactive?: boolean;
  children: React.ReactNode;
}

export const Card: React.FC<CardProps> = ({
  variant = 'elevated',
  padding = 'md',
  interactive = false,
  children,
}) => {
  const Component = interactive ? 'button' : 'div';

  return (
    <Component
      className={`
        card
        card--${variant}
        card--padding-${padding}
        ${interactive ? 'card--interactive' : ''}
      `}
      {...(interactive && { role: 'button', tabIndex: 0 })}
    >
      {children}
    </Component>
  );
};

CSS:

.card {
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.card--elevated {
  box-shadow: var(--shadow-md);
}

.card--outlined {
  border: 1px solid var(--color-border);
}

.card--filled {
  background: var(--color-surface-variant);
}

.card--interactive {
  cursor: pointer;
  transition: transform 0.2s, box-shadow 0.2s;

  &:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-lg);
  }

  &:focus-visible {
    outline: 2px solid var(--color-focus);
    outline-offset: 2px;
  }
}

.card--padding-sm { padding: var(--space-3); }
.card--padding-md { padding: var(--space-4); }
.card--padding-lg { padding: var(--space-6); }

Formular-Eingabekomponente

Barrierefreie Formulareingabe:

interface InputProps {
  label: string;
  error?: string;
  hint?: string;
  required?: boolean;
  type?: 'text' | 'email' | 'password' | 'number';
}

export const Input: React.FC<InputProps> = ({
  label,
  error,
  hint,
  required = false,
  type = 'text',
  ...props
}) => {
  const id = useId();
  const hintId = `${id}-hint`;
  const errorId = `${id}-error`;

  return (
    <div className="input-wrapper">
      <label htmlFor={id} className="input-label">
        {label}
        {required && <span aria-label="required">*</span>}
      </label>

      {hint && (
        <p id={hintId} className="input-hint">
          {hint}
        </p>
      )}

      <input
        id={id}
        type={type}
        className={`input ${error ? 'input--error' : ''}`}
        aria-required={required}
        aria-invalid={!!error}
        aria-describedby={error ? errorId : hint ? hintId : undefined}
        {...props}
      />

      {error && (
        <p id={errorId} className="input-error" role="alert">
          {error}
        </p>
      )}
    </div>
  );
};

Design-Tokens

CSS-Benutzerdefinierte Eigenschaften für das Designsystem:

:root {
  /* Farben - Primär */
  --color-primary: #0066FF;
  --color-primary-hover: #0052CC;
  --color-on-primary: #FFFFFF;

  /* Farben - Oberfläche */
  --color-surface: #FFFFFF;
  --color-surface-variant: #F5F5F5;
  --color-on-surface: #1A1A1A;

  /* Farben - Rahmen */
  --color-border: #E0E0E0;
  --color-border-hover: #BDBDBD;

  /* Farben - Semantisch */
  --color-error: #D32F2F;
  --color-success: #388E3C;
  --color-warning: #F57C00;
  --color-info: #1976D2;

  /* Abstandsskala (8px Basis) */
  --space-1: 0.25rem;  /* 4px */
  --space-2: 0.5rem;   /* 8px */
  --space-3: 0.75rem;  /* 12px */
  --space-4: 1rem;     /* 16px */
  --space-5: 1.5rem;   /* 24px */
  --space-6: 2rem;     /* 32px */
  --space-8: 3rem;     /* 48px */
  --space-10: 4rem;    /* 64px */

  /* Typografie-Skala */
  --text-xs: 0.75rem;    /* 12px */
  --text-sm: 0.875rem;   /* 14px */
  --text-base: 1rem;     /* 16px */
  --text-lg: 1.125rem;   /* 18px */
  --text-xl: 1.25rem;    /* 20px */
  --text-2xl: 1.5rem;    /* 24px */
  --text-3xl: 1.875rem;  /* 30px */
  --text-4xl: 2.25rem;   /* 36px */

  /* Schriftfamilien */
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-mono: "SF Mono", Monaco, "Cascadia Code", monospace;

  /* Zeilenhöhen */
  --leading-tight: 1.25;
  --leading-normal: 1.5;
  --leading-relaxed: 1.75;

  /* Rahmenradius */
  --radius-sm: 0.25rem;  /* 4px */
  --radius-md: 0.5rem;   /* 8px */
  --radius-lg: 1rem;     /* 16px */
  --radius-full: 9999px;

  /* Schatten */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
  --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
  --shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.15);

  /* Fokusring */
  --color-focus: #0066FF;

  /* Übergänge */
  --transition-fast: 150ms ease;
  --transition-base: 200ms ease;
  --transition-slow: 300ms ease;
}

/* Dunkelmodus */
@media (prefers-color-scheme: dark) {
  :root {
    --color-surface: #1A1A1A;
    --color-surface-variant: #2A2A2A;
    --color-on-surface: #FFFFFF;
    --color-border: #3A3A3A;
  }
}

Responsive Design-Muster

Mobile-First Breakpoints

/* Mobile-First-Ansatz */
.container {
  padding: var(--space-4);

  /* Tablet: 768px und größer */
  @media (min-width: 48rem) {
    padding: var(--space-6);
  }

  /* Desktop: 1024px und größer */
  @media (min-width: 64rem) {
    padding: var(--space-8);
    max-width: 1200px;
    margin: 0 auto;
  }
}

Flüssige Typografie

/* Responsive Typografie */
h1 {
  font-size: clamp(2rem, 5vw, 3.5rem);
  line-height: var(--leading-tight);
}

h2 {
  font-size: clamp(1.5rem, 4vw, 2.5rem);
}

p {
  font-size: clamp(1rem, 2vw, 1.125rem);
  line-height: var(--leading-normal);
}

Grid-Layouts

/* Responsives Grid */
.grid {
  display: grid;
  gap: var(--space-4);

  /* Auto-fit Spalten (min 280px) */
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

/* 12-Spalten-Grid-System */
.grid-12 {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--space-4);
}

.col-span-4 {
  grid-column: span 4;
}

/* Stapeln auf mobilen Geräten */
@media (max-width: 48rem) {
  .col-span-4 {
    grid-column: span 12;
  }
}

Barrierefreiheitsmuster

Skip Links

export const SkipLink = () => (
  <a href="#main-content" className="skip-link">
    Zum Hauptinhalt springen
  </a>
);
.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  background: var(--color-primary);
  color: var(--color-on-primary);
  padding: var(--space-2) var(--space-4);
  text-decoration: none;
  z-index: 100;

  &:focus {
    top: 0;
  }
}

Fokusverwaltung

// Modal mit Fokusfalle
export const Modal = ({ isOpen, onClose, children }) => {
  const modalRef = useRef(null);

  useEffect(() => {
    if (isOpen) {
      // Aktuell fokussiertes Element speichern
      const previouslyFocused = document.activeElement;

      // Erstes fokussierbares Element im Modal fokussieren
      const firstFocusable = modalRef.current?.querySelector(
        'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
      );
      firstFocusable?.focus();

      // Fokus beim Schließen wiederherstellen
      return () => previouslyFocused?.focus();
    }
  }, [isOpen]);

  if (!isOpen) return null;

  return (
    <div
      ref={modalRef}
      role="dialog"
      aria-modal="true"
      className="modal-overlay"
    >
      <div className="modal">
        {children}
      </div>
    </div>
  );
};

ARIA-Labels

// Icon-Button mit barrierefreiem Label
export const IconButton = ({ icon, label, ...props }) => (
  <button
    aria-label={label}
    className="icon-button"
    {...props}
  >
    <span aria-hidden="true">{icon}</span>
  </button>
);

// Ladezustand
export const LoadingButton = ({ loading, children, ...props }) => (
  <button
    aria-busy={loading}
    aria-live="polite"
    disabled={loading}
    {...props}
  >
    {loading ? 'Wird geladen...' : children}
  </button>
);

Leistungsoptimierung

Kritisches CSS

<!-- Inline kritisches CSS -->
<style>
  /* Stile oberhalb der Falz */
  body { margin: 0; font-family: var(--font-sans); }
  .header { /* kritische Header-Stile */ }
  .hero { /* kritische Hero-Stile */ }
</style>

<!-- Vollständiges Stylesheet asynchron laden -->
<link rel="stylesheet" href="styles.css" media="print" onload="this.media='all'">

Lazy Loading von Bildern

export const LazyImage = ({ src, alt, ...props }) => (
  <img
    src={src}
    alt={alt}
    loading="lazy"
    decoding="async"
    {...props}
  />
);

Code-Splitting

// Lazy Loading in React
const Dashboard = lazy(() => import('./Dashboard'));

function App() {
  return (
    <Suspense fallback={<Loading />}>
      <Dashboard />
    </Suspense>
  );
}

Moderne CSS-Techniken

Container Queries

.card {
  container-type: inline-size;
}

.card-content {
  display: flex;
  flex-direction: column;

  /* Wechsel zu Zeilenlayout, wenn Container > 400px */
  @container (min-width: 400px) {
    flex-direction: row;
  }
}

CSS Grid Auto-Fit

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: var(--space-4);
}

Benutzerdefinierte Eigenschaften für Theming

/* Helles Theme (Standard) */
:root {
  --bg: #ffffff;
  --text: #000000;
}

/* Dunkles Theme */
[data-theme="dark"] {
  --bg: #000000;
  --text: #ffffff;
}

body {
  background: var(--bg);
  color: var(--text);
}

Komponentenbibliothek-Struktur

src/
├── components/
│   ├── Button/
│   │   ├── Button.tsx
│   │   ├── Button.css
│   │   ├── Button.test.tsx
│   │   └── Button.stories.tsx
│   ├── Card/
│   ├── Input/
│   └── index.ts
├── tokens/
│   ├── colors.css
│   ├── spacing.css
│   ├── typography.css
│   └── index.css
├── utils/
│   ├── a11y.ts
│   └── responsive.ts
└── index.ts

Verwenden dieses Skills

Komponente generieren

./scripts/generate_component.sh Button

Erstellt Komponente mit:

  • TypeScript/JSX-Datei
  • CSS-Modul
  • Testdatei
  • Storybook-Story
  • Barrierefreiheitsprüfungen

Designsystem einrichten

./scripts/setup_design_system.sh

Erstellt:

  • Design-Tokens (CSS-Benutzerdefinierte Eigenschaften)
  • Basis-Stile
  • Komponentenvorlagen
  • Dokumentationsstruktur

Barrierefreiheitsaudit

./scripts/audit_accessibility.sh

Prüft:

  • Farbkontrastverhältnisse
  • Tastaturnavigation
  • ARIA-Attribute
  • Semantisches HTML
  • Fokusverwaltung

Best Practices

Komponentendesign

✅ TUN:

  • Verwende semantisches HTML
  • Stelle Tastaturzugänglichkeit sicher
  • Gib ARIA-Labels an
  • Unterstütze sowohl hellen als auch dunklen Modus

❌ NICHT TUN:

  • Verwende keine nicht-semantischen Divs für Buttons/Links
  • Verlasse dich nicht nur auf Farbe zur Informationsvermittlung
  • Entferne keine Fokusindikatoren
  • Vergiss nicht die Touch-Ziele auf mobilen Geräten
  • Verwende keine festen Pixelgrößen für Text

Leistungsoptimierung

✅ TUN:

  • Verwende Lazy Loading für Bilder
  • Minimiere CSS/JS-Bundle-Größe
  • Optimiere Schriftarten
  • Verwende asynchrones Laden für nicht kritische Ressourcen

❌ NICHT TUN:

  • Lade kein gesamtes CSS auf einmal
  • Verwende keine schweren Bibliotheken für einfache Aufgaben
  • Vergiss nicht die Tree Shaking-Konfiguration
  • Blockiere nicht das Rendern mit synchronen Skripten

Tools & Integrationen

Design-Tools

  • Figma
  • Sketch
  • Adobe XD

Test-Tools

  • Jest
  • Testing Library
  • Cypress
  • Axe (Barrierefreiheit)

Build-Tools

  • Vite
  • Webpack
  • esbuild
  • PostCSS

Framework-Integrationen

  • React (Create React App, Next.js)
  • Vue (Vue CLI, Nuxt)
  • Svelte (SvelteKit)

Lizenz

MIT

Individual skills in this repo

This repo contains 5 individual skills — each has its own dedicated page.

Samueladewole/claude-skills

Create API handoff documentation for frontend developers. Use when backend work is complete and needs to be documented for frontend integration, or user says 'create handoff', 'document API', 'frontend handoff', or 'API documentation'.

Samueladewole/claude-skills

Set up Tailwind CSS v4 in Expo with react-native-css and NativeWind v5 for universal styling

Samueladewole/claude-skills

Document frontend data needs for backend developers. Use when frontend needs to communicate API requirements to backend, or user says 'backend requirements', 'what data do I need', 'API requirements', or is describing data needs for a UI.

Samueladewole/claude-skills

Master Next.js 14+ App Router with Server Components, streaming, parallel routes, and advanced data fetching. Use when building Next.js applications, implementing SSR/SSG, or optimizing React Server Components.

Samueladewole/claude-skills

Analyze a short-form video (TikTok, Instagram Reel, YouTube Short, or any MP4) to extract its full transcript, understand why it performed, and generate concrete repurposing ideas. Use this skill whenever the user asks to: analyze a video, understand why something went viral, reverse-engineer a creator's content, extract a transcript from a video, figure out what makes a video perform, or get repurposing ideas from a video. Also trigger when the user says things like "why did this perform", "what's the hook here", "can I repurpose this", "analyze this TikTok/Reel", or drops a video file path or URL.

Verwandte Skills