14: Color, Backgrounds & Borders

Why your pretty color looks muddy on screen. Compare hex, rgb, and hsl, then build a palette with only a few colors.

Color formats

FormatExampleNotes
hex#0b57d0Most common; #fff = #ffffff
rgbrgb(11 87 208)0-255 per channel; rgb(11 87 208 / 0.5) with alpha
hslhsl(217 89% 43%)Hue/Sat/Light are intuitive to tweak
keywordtomato, currentColor, transparentNamed; currentColor = element's color
#0b57d0
hex
rgb(… / 0.15)
transparent
hsl(217…)
same blue
currentColor
border = text color
.a { color: #0b57d0; }                    /* hex */
.b { background: rgb(11 87 208 / 0.1); }  /* with alpha */
.c { color: hsl(217 89% 43%); }           /* hsl */
.d { border: 2px solid currentColor; }    /* matches color */
Pick with hsl: Need a lighter blue? Keep hue, bump lightness: hsl(217 89% 60%). Hex is opaque for that.

Backgrounds and gradients

background-color
linear-gradient
radial-gradient
conic-gradient
.a { background-color: #eef6ff; }
.b { background: linear-gradient(135deg, #0b57d0, #7c3aed); }
.c { background: radial-gradient(circle, #fff7cc, #f0d27a); }

Gradients are background-image under the hood, meaning you can layer them.


Borders, radius, shadows

border:1px solid #111
border-radius:12px
box-shadow
dashed
pill with 999px
double shadow (layered)
.card {
  border: 1px solid #ddd;
  border-radius: 12px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.08), 0 8px 24px rgba(0,0,0,0.08);
}
.pill { border-radius: 999px; } /* fully rounded */
.circle { border-radius: 50%; width: 48px; height: 48px; }

Opacity & contrast

opacity 1 is full
opacity 0.6 is muted
opacity 0.3 is faint
contrast 21:1
#888 on white is 3.5:1
#bbb on white is 1.8:1
Check with DevTools color picker for contrast ratio
A11y: Normal text needs 4.5:1 contrast (WCAG AA). DevTools color picker shows the ratio, so you can aim for it. Don't put light gray on white.

Theme with CSS variables without JS

CSS variables let you change --accent and shift the whole theme.
--bg, --fg, --accent at :root
:root {
  --bg: #ffffff;
  --fg: #111111;
  --accent: #0b57d0;
  --radius: 12px;
}
.card {
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
}

Variables cascade, so you can override per section: .dark { --bg: #111; --fg: #fff; }

Exercise: Theme switch with just CSS variables (20 min)
  1. Define --bg, --fg, --accent, --radius, and --shadow on :root.
  2. Build 3 cards using only variables for colors, borders, and shadows.
  3. Duplicate cards inside <section class="dark"> with .dark { --bg:#111; --fg:#fff; } for instant dark mode with no JS.
  4. Check contrast on both themes and fix any failures.
Prev13: Typography Next15: Forms & Inputs