DEV Community

GavinGeng
GavinGeng

Posted on Originally published at huegrad.com

Why a Color Palette Can Look Good and Still Be Hard to Read

A palette can feel balanced in a mood board and fail completely in a real interface. The problem is often not taste. It is contrast: the measurable separation between foreground and background that allows text, icons, and controls to remain legible.

Contrast is a usability requirement

Text is not decoration. People need to read it in different lighting conditions, on different screens, and at different sizes. A light gray label on a white card may look refined in a design file but become difficult to scan on a dim laptop or a low-quality display.

The same issue affects buttons, form borders, placeholder text, charts, and focus indicators. If a user cannot distinguish an interactive state, the interface feels broken even when the underlying code works.

Do not trust color alone

Two colors can appear different because of surrounding colors, shadows, or the display they are viewed on. A contrast checker gives you a more consistent starting point than visual judgment alone. Test the actual foreground and background pair, not just the two swatches in isolation.

It is also worth checking more than body text. Large text, icons, disabled states, and decorative elements have different roles. Disabled content may intentionally have lower contrast, but instructions and controls that users must understand should not be treated as disabled merely because a lighter style looks cleaner.

A practical checking workflow

HueGrad’s contrast workflow is useful during design and implementation:

  1. Enter or select the foreground color.
  2. Enter or select the background color.
  3. Review the contrast result and the applicable text-size guidance.
  4. Test the pair in the actual component, including hover, focus, and visited states.
  5. Adjust lightness or saturation while keeping the brand character intact.

The goal is not to flatten every design into black text on white. Small, deliberate changes can preserve the palette: darken the foreground slightly, lighten the background, reduce a low-contrast tint, or reserve a stronger accent for text and controls.

Fix the relationship, not just one color

When a palette fails, changing the brand color everywhere may create new inconsistencies. Instead, define roles. A primary brand color can remain the visual anchor while a darker text variant handles small labels. A soft background can stay in place while cards receive a stronger border or surface difference.

This role-based approach is especially useful for design systems. Instead of naming a color “light blue,” name its purpose: surface-muted, text-secondary, border-default, or action-primary. Then test the combinations that users will actually encounter.

Common traps

Gradients are easy to misjudge because contrast changes across the surface. A text color that works at the left edge may disappear in the middle. Add a readable overlay, choose a safer text color, or test the worst part of the gradient rather than its average appearance.

Transparency creates another trap. A semitransparent white label may look strong over one image and vanish over another. Test it against representative content, not a blank placeholder.

Finally, do not fix contrast by adding a heavy shadow everywhere. Shadows can help in a specific component, but they are not a substitute for a clear foreground/background relationship.

The useful standard

Good color work combines expression with readable structure. Start with the palette you like, test the combinations that matter, and make the smallest role-specific adjustment that keeps the interface understandable. The result usually looks more intentional because every color has a job.

Check a foreground/background pair here: https://huegrad.com/blog-wcag-contrast

Top comments (0)