—CSS Series · Post 05: Color

Colors & Units — CodeHerWay
CSS Series · Post 05

Colors & Units
The Language of Visual Decisions

Every color you see on every website was written as a value in a CSS file. This post gives you full control over that — and teaches you which units to reach for, and when.

CSS Beginner Series: Post 05 ~12 min read

💬 "What Even Is #ff69b4?"

At some point you copy-paste a color value and it works — but you have no idea why #ff69b4 is pink, or what rgba(0,0,0,0.5) means, or why one tutorial uses px and another uses rem. It all feels like magic codes you have to look up every time.

It's not magic. CSS has multiple color systems and multiple unit systems, and each one was built for a different use case. Once you understand what each one does, you start making deliberate choices instead of guessing.

🧠 Mindset First

Colors and units aren't just technical values — they're design decisions. Choosing rem over px for font sizes, or rgba over hex for overlays, reflects a level of intentionality that separates beginner CSS from professional CSS.

🧱 Color Systems

HEX — The Most Common Format

HEX is the format you'll see most often. It's a six-character code that represents red, green, and blue as pairs of hexadecimal digits — base 16, where letters A–F represent 10–15.

HEX
#ff69b4
HEX
#b44aff
HEX
#0a0a0f
HEX
#69d2e7
styles.css
CSS · HEX
/* Full 6-digit HEX — #RRGGBB */ .heading { color: #ff69b4; } /* pink */ .bg { background: #0a0a0f; } /* near-black */ .border { border-color: #b44aff; } /* purple */ /* Shorthand — #RGB (only when both digits match) */ .white { color: #fff; } /* = #ffffff */ .black { color: #000; } /* = #000000 */ /* HEX with alpha — 8 digits, last two = opacity */ .ghost { background: #ff69b480; } /* 50% transparent pink */

RGB and RGBA — Red, Green, Blue (+ Alpha)

RGB uses three numbers 0–255 for red, green, and blue. RGBA adds a fourth value for transparency — alpha — from 0 (invisible) to 1 (fully opaque). This is the most readable format for colors where opacity matters.

rgba(180, 74, 255, 1.0) — fully opaque
rgba(180, 74, 255, 0.6) — 60% opacity
rgba(180, 74, 255, 0.25) — 25% opacity
rgba(180, 74, 255, 0.06) — subtle tint
styles.css
CSS · RGB / RGBA
/* rgb(red, green, blue) — each 0–255 */ .heading { color: rgb(255, 105, 180); } /* rgba — same, plus alpha 0–1 */ .overlay { background: rgba(0, 0, 0, 0.5); } /* dark overlay */ .card { border: 1px solid rgba(255,255,255,0.08); } /* subtle border */ .callout { background: rgba(180,74,255,0.06); } /* very faint tint */ /* Modern syntax — spaces, no commas */ .modern { color: rgb(255 105 180 / 80%); }
✦ RGBA Is Your Best Friend for Subtle UI

Low-opacity colors for borders, backgrounds, and overlays make designs feel layered and polished without requiring exact color matching. rgba(255,255,255,0.08) on a dark background gives you a barely-there border that works with any accent color. This trick is used on virtually every modern dark UI.

HSL — Hue, Saturation, Lightness

HSL is the most human-readable color system. Instead of thinking in RGB values, you describe a color the way a person would: what hue it is, how vivid it is, and how light or dark it is.

styles.css
CSS · HSL / HSLA
/* hsl(hue, saturation%, lightness%) */ /* hue: 0–360° on the color wheel */ /* saturation: 0% = gray, 100% = full color */ /* lightness: 0% = black, 50% = pure, 100% = white */ .pink { color: hsl(330, 100%, 71%); } .purple { color: hsl(277, 100%, 64%); } /* HSL makes color variations easy — just adjust L */ .pink-light { background: hsl(330, 100%, 90%); } /* very light */ .pink-dark { background: hsl(330, 100%, 30%); } /* deep */ .pink-muted { background: hsl(330, 30%, 71%); } /* desaturated */ /* HSLA — add alpha */ .glow { box-shadow: 0 0 24px hsla(330, 100%, 71%, 0.3); }
ℹ️ Named Colors

CSS also has 140+ built-in named colors: hotpink, rebeccapurple, dodgerblue, tomato. They work everywhere a color value is accepted, but they give you no control over opacity or variation. Good for quick prototyping, not production design systems.

🧱 Units

CSS has two categories of units: absolute (fixed regardless of context) and relative (calculated based on something else). Knowing which to reach for is one of the clearest signs of CSS maturity.

Absolute Units
Fixed size. Doesn't scale with anything.
  • px — pixels. The most common absolute unit. Use for borders, shadows, fine details.
  • Other absolutes (cm, mm, in, pt) exist but are almost never used in web CSS.
Relative Units
Calculated based on something else. Scales naturally.
  • rem — relative to root font size. Best for typography and spacing.
  • em — relative to the parent's font size. Useful but can compound unexpectedly.
  • % — relative to the parent element's size. Great for widths and fluid layouts.
  • vh / vw — percentage of the viewport height/width. Hero sections, full-screen layouts.

px — Pixels

styles.css
CSS · px
/* px is best for things that should NEVER scale */ .card { border: 1px solid rgba(255,255,255,0.08); /* fine line */ border-radius: 12px; box-shadow: 0 8px 32px rgba(0,0,0,0.4); } /* Avoid px for font-size — it ignores browser zoom preferences */ .avoid-this { font-size: 16px; } /* won't scale if user increases browser font size */

rem — Root Em

styles.css
CSS · rem
/* Browser default: 1rem = 16px */ /* You can change the base by setting html font-size */ html { font-size: 16px; } /* 1rem = 16px */ body { font-size: 1rem; } /* 16px */ h1 { font-size: 3rem; } /* 48px */ h2 { font-size: 1.75rem; } /* 28px */ small { font-size: 0.875rem;} /* 14px */ /* rem also works for spacing */ .section { padding: 4rem 0; } /* 64px top+bottom */ .gap { margin-bottom: 1.5rem; } /* 24px */

% — Percentage

styles.css
CSS · %
/* % is relative to the PARENT element's size */ .container { width: 860px; } .sidebar { width: 30%; /* 30% of 860px = 258px */ } .main { width: 70%; /* 70% of 860px = 602px */ } /* % heights are tricky — parent needs an explicit height */ .hero-img { width: 100%; /* fills its container — very common */ height: auto; /* maintains aspect ratio */ }

vh and vw — Viewport Units

styles.css
CSS · vh / vw
/* 1vh = 1% of the viewport height */ /* 1vw = 1% of the viewport width */ /* Full-screen hero section */ .hero { min-height: 100vh; /* full screen height */ width: 100vw; /* full screen width */ } /* Fluid font scaling with clamp() */ h1 { font-size: clamp(32px, 5vw, 64px); /* min 32px, scales with viewport, max 64px */ }

Quick Reference: When to Use What

UnitUse It ForAvoid It For
pxBorders, shadows, border-radius, fine detailsFont sizes, spacing systems
remFont sizes, spacing, padding, marginsBorders (overkill)
emSizing relative to local font (icons, buttons)Large-scale layout (compounding is confusing)
%Widths, fluid containers, responsive columnsHeights (unless parent has fixed height)
vh / vwFull-screen sections, viewport-aware sizingFont sizes (can cause tiny text on mobile)
🛠

Mini Build: A Consistent Color Theme

You're going to build a simple color system using CSS variables, then apply it using the right color format for each job. This is exactly how real design systems are built — define once, use everywhere.

01

Define your color palette as CSS variables on :root. We'll cover variables in depth later — for now, treat them as named colors you define once and reuse everywhere.

styles.css
CSS
:root { /* Base colors */ --bg: #0a0a0f; --surface: #12121a; --text: #e0e0e8; --muted: #9595a8; /* Accent — HEX for the pure color */ --accent: #ff69b4; /* Accent with transparency — RGBA for layers */ --accent-glow: rgba(255, 105, 180, 0.15); --accent-border: rgba(255, 105, 180, 0.25); } * { margin: 0; padding: 0; box-sizing: border-box; } body { background: var(--bg); color: var(--text); font-family: sans-serif; font-size: 1rem; /* rem — scales with browser */ line-height: 1.75; padding: 3rem 2rem; /* rem — consistent rhythm */ }
02

Style a card using your color system. Notice which format goes where: HEX for solid colors, RGBA for transparent layers, px for fine structural details, rem for spacing and type.

styles.css
CSS
.card { background: var(--surface); border: 1px solid var(--accent-border); /* RGBA — subtle */ border-radius: 12px; /* px — fine detail */ padding: 1.5rem; /* rem — spacing */ max-width: 380px; } .card:hover { background: var(--accent-glow); /* RGBA tint on hover */ border-color: var(--accent); /* HEX — full accent */ } .card-title { color: var(--accent); /* HEX */ font-size: 1.25rem; /* rem */ margin-bottom: 0.5rem; } .card-body { color: var(--muted); font-size: 0.9rem; }
03

Change your whole theme by editing just two lines. Swap --accent to #69d2e7 (sky blue) and --accent-border to rgba(105, 210, 231, 0.25). Every element that references those variables updates instantly. That's the power of a color system.

💛 You Just Learned to Think in Color Systems

Most beginners copy-paste colors without knowing what format they're looking at. Now you know what each format is for — HEX for solid accent colors, RGBA when you need transparency, HSL when you want to reason about lightness and saturation directly.

  • HEX: the standard format for solid colors — 6 digits, R/G/B
  • RGBA: your go-to for overlays, borders, tints — anything where opacity matters
  • HSL: the most human-readable format, great for generating color families
  • px for precise details. rem for everything type and spacing related.
  • % for fluid widths. vh/vw for full-viewport layouts.
  • CSS variables tie it all together into a theme you can change in one place

Next: Display & Positioning — how CSS decides where elements sit, how big they are, and how they stack. This is the post that makes position: absolute finally make sense.

🧾 DevFession

I used HEX for everything for way too long. Even for transparent borders. My code was full of things like border: 1px solid #ffffff14 — which I had to look up every single time because HEX alpha is not intuitive at all. (#14 in hex is 20 in decimal, which is... roughly 8% opacity. You're welcome.)

The day I switched transparent UI colors to RGBA, my CSS became immediately more readable. rgba(255,255,255,0.08) — I can just read that. 8% white. Done. I don't need a hex-to-decimal converter to understand my own stylesheet anymore.

Use the right format for the job. Your future self will be very grateful.

Previous
Previous

—CSS Series · Post 06: Display & Positioning

Next
Next

—CSS Series · Post 04: Typography