Design

Building a Perfect Color Palette for Your Design System

Dmitriy Hulak
Dmitriy Hulak
15 min read0 views

Building a Perfect Color Palette for Your Design System

A well-crafted color palette is the foundation of any successful design system. It ensures consistency, improves accessibility, and scales effortlessly as your product grows. Let's build one from scratch.

The Anatomy of a Design System Color Palette

A complete color palette typically includes:

  • Brand colors - Primary and secondary brand identity colors
  • Neutral colors - Grays for text, borders, and backgrounds
  • Semantic colors - Success, warning, error, and info states
  • Background colors - Surface levels for depth and hierarchy
  • Interactive colors - Hover, active, and focus states
  • Step 1: Choose Your Primary Color

    Start with your brand's primary color. This is usually your most recognizable brand color and will be used for primary actions, links, and key UI elements.

    Pro tip: Pick a color in the middle of the lightness range (40-60% in HSL). This gives you room to create lighter and darker variations.

    :root {
      --primary-500: hsl(220, 90%, 56%);
    }
    

    Step 2: Generate a Complete Scale

    Create 9-11 shades of your primary color, from very light to very dark. A common approach is the 50-900 scale:

    :root {
      --primary-50: hsl(220, 90%, 96%);
      --primary-100: hsl(220, 90%, 92%);
      --primary-200: hsl(220, 90%, 84%);
      --primary-300: hsl(220, 90%, 72%);
      --primary-400: hsl(220, 90%, 64%);
      --primary-500: hsl(220, 90%, 56%);
      --primary-600: hsl(220, 90%, 48%);
      --primary-700: hsl(220, 90%, 40%);
      --primary-800: hsl(220, 90%, 32%);
      --primary-900: hsl(220, 90%, 24%);
    }
    

    Step 3: Build Your Neutral Scale

    Neutrals are the workhorses of your palette. They're used for text, backgrounds, borders, and subtle UI elements.

    Important: Neutrals should have very low saturation (0-5%). Pure grays (0% saturation) can feel cold, while slightly warm or cool grays (2-5% saturation) add personality.

    :root {
      --neutral-50: hsl(220, 5%, 98%);
      --neutral-100: hsl(220, 5%, 96%);
      --neutral-200: hsl(220, 5%, 92%);
      --neutral-300: hsl(220, 4%, 84%);
      --neutral-400: hsl(220, 3%, 64%);
      --neutral-500: hsl(220, 2%, 48%);
      --neutral-600: hsl(220, 2%, 36%);
      --neutral-700: hsl(220, 3%, 24%);
      --neutral-800: hsl(220, 4%, 16%);
      --neutral-900: hsl(220, 5%, 12%);
    }
    

    Step 4: Add Semantic Colors

    Create color scales for common UI states:

    :root {
      --success-500: hsl(142, 76%, 36%);
      --warning-500: hsl(38, 92%, 50%);
      --error-500: hsl(0, 84%, 60%);
      --info-500: hsl(200, 94%, 46%);
    }
    

    Generate complete scales (50-900) for each semantic color using the same approach as your primary color.

    Step 5: Ensure Accessibility

    All text-background color combinations must meet WCAG contrast requirements:

    • Normal text: Minimum 4.5:1 contrast ratio
    • Large text (18px+): Minimum 3:1 contrast ratio
    • UI elements: Minimum 3:1 contrast ratio
    Use tools like WebAIM Contrast Checker to verify your combinations.

    Step 6: Plan for Dark Mode

    Create a dark mode palette by:

  • Inverting your neutral scale
  • Reducing saturation of bright colors (they appear too intense on dark backgrounds)
  • Testing all combinations for sufficient contrast
  • [data-theme="dark"] {
      --background: var(--neutral-900);
      --surface: var(--neutral-800);
      --text-primary: var(--neutral-100);
      --text-secondary: var(--neutral-400);

    --primary-500: hsl(220, 75%, 64%); }

    Step 7: Create Semantic Tokens

    Map your raw color values to semantic names:

    :root {
      --color-background-primary: var(--neutral-50);
      --color-background-secondary: var(--neutral-100);
      --color-text-primary: var(--neutral-900);
      --color-text-secondary: var(--neutral-600);
      --color-border-default: var(--neutral-200);
      --color-action-primary: var(--primary-500);
      --color-action-primary-hover: var(--primary-600);
    }
    

    This abstraction makes it easy to swap themes and maintain consistency.

    Best Practices

  • Limit your palette - Too many colors create chaos. Stick to 1-2 primary colors and a solid neutral scale.
  • Test in context - Colors look different on various backgrounds and next to other colors.
  • Use HSL - It's more intuitive than RGB for creating color variations.
  • Document everything - Include usage guidelines for each color.
  • Build tools - Create Figma color styles or CSS custom properties for easy adoption.
  • Tools to Help You

    Conclusion

    A well-designed color palette is both art and science. It requires careful consideration of brand identity, accessibility, and scalability. Take time to build it right, and it will serve your design system for years to come.

    Related posts

    Continue reading on nearby topics.

    Token-Driven Theming for Light and Dark ModesDesign a scalable color token system for light and dark themes with predictable contrast and maintainable component mapping.Accessible Color Contrast Systems for Real ProductsBuild contrast-safe color systems that scale from marketing pages to dashboards without breaking readability and accessibility.WCAG in the Messy Middle of Real Frontend: What Teams Miss After the AuditA long practical editorial on WCAG in real products: not theory, but the small interface decisions that quietly break accessibility after sprint pressure, rewrites, and content growth.Neumorphism and Soft UI: The Art of Subtle ShadowsDeep dive into neumorphism design - learn how to create soft, embossed UI elements with perfect shadows, highlights, and accessibility considerations.

    Comments

    0

    Sign in to leave a comment.

    No comments yet. Be the first.