Typography and color
Apply colors and opacity
Use palette utilities for text, backgrounds, borders, and opacity modifiers while preserving sufficient visual contrast.
Color utilities are built from three parts: a property, a color name, and a shade.
<p class="border-blue-200 bg-blue-50 text-blue-950">Saved</p>
The prefix picks the CSS property: text-* for color, bg-* for background-color, border-* for border-color, fill-* and stroke-* for SVG. The name and number pick a value from the palette. blue-50 is a very light blue, blue-950 is almost black.
Using the same shade number on different properties doesn’t give the same visual weight. A blue-600 background covers a large area. A blue-600 border is a thin line. Judge colors in context, not by their number.
Opacity with a slash
Add / and a number to make a color translucent:
<div class="bg-black/50 text-white">Overlay label</div>
The background is 50% transparent black. The text stays fully white. This is different from opacity-50, which fades the whole element, children included. Use opacity-50 on a photo overlay and you also fade the label on top of it, and the contrast collapses.
Contrast against the real background
Contrast is measured against what’s actually behind the text after everything is composited. text-white on bg-blue-600/70 looks different on a white page and on a dark one. Test every state: normal, hover, focus, disabled, selected, and dark mode. A screenshot of the default state tells you almost nothing.
Color is never the only signal
Some visitors don’t see red as red. Pair an error color with text or an icon. Pair a selected color with a shape or a label. Pair a focus color with a visible outline. If the interface matters, check it in forced-colors and high-contrast modes too.
From palette to tokens
Raw palette classes like bg-blue-600 are great while you explore. Once a color means something stable, like “brand”, “surface”, or “danger”, define a theme token for it. Then a redesign is one token change, not a search for every blue-600 in the codebase.
Browser contrast tools help, but look at the actual rendered state and text size. Gradients, transparency, images, and antialiasing can make a nominal ratio misleading.
Try this: build a success message and an error message, each with text, border, and background colors. Place them over two different parent backgrounds. Then turn off color in the DevTools rendering emulation and check that the meaning still comes through.
Lesson completed