
Quick answer: CSS has many ways to write a colour — hex, named, rgb(), hsl() and the modern oklch() — and color-mix() derives a consistent palette from a few base colours. For sizes, use rem for text and spacing, ch for line lengths, and pick the viewport unit that matches the behaviour you want: dvh, svh or lvh.
Table of Contents
CSS color-mix(): colour syntax, then and now
.a { color: #0f766e; } /* hex */
.b { color: rgb(15 118 110); } /* rgb, space-separated */
.c { color: hsl(175 80% 24%); } /* hsl: hue, saturation, lightness */
.d { color: oklch(48% 0.09 180); } /* perceptually uniform */
.e { color: rgb(15 118 110 / 0.6); } /* with transparency */The modern space-separated syntax inside rgb() and hsl() is the current style; the old comma form still works. oklch() is worth learning because its lightness channel is perceptually even — two colours with the same lightness value actually look equally light, which is not true in HSL.
Derive a palette with CSS color-mix()
Instead of hard-coding ten shades of one brand colour, define the base and mix the rest. Change the base once and the whole palette follows.
:root {
--brand: oklch(55% 0.12 180);
--brand-light: color-mix(in oklch, var(--brand), white 35%);
--brand-dark: color-mix(in oklch, var(--brand), black 25%);
}
.button { background: var(--brand); }
.button:hover { background: var(--brand-dark); }The interpolation space matters. Mixing in oklab or in oklch blends through a perceptually even path, so the midpoint of teal and white looks like teal, not a muddy grey — which is what happens in the default sRGB space.
Units: which one, and when to use CSS color-mix()
| Unit | Relative to | Use for |
|---|---|---|
rem | The root font size | Text, spacing, most sizing |
em | The element’s own font size | Padding that scales with its text |
ch | The width of the 0 character | Line length limits |
% | The parent’s matching size | Fluid widths |
vw / vh | The viewport | Full-screen sections |
dvh | Dynamic viewport height | Mobile full-height layouts |
Prefer rem for anything a user might want to zoom: because it is relative to the root font size, changing the browser’s default text size scales the whole layout proportionally. Use ch to set a comfortable reading width — max-inline-size: 65ch is roughly the classic 60-to-75 character target.
The viewport-unit trap on mobile
On phones, browser bars appear and disappear as you scroll, which changes the visible height. The classic vh corresponds to the large viewport and can push content under the URL bar. Three newer units give you control:
.hero {
min-height: 100svh; /* small viewport: never hidden behind browser UI */
/* 100dvh follows the bars as they move, 100lvh assumes they are gone */
}svh— the smallest viewport, stable while the bars are visible. Best for a first full-screen section.dvh— tracks the bars as they slide, but can resize during scrolling.lvh— the largest viewport, as if no bars were present.
For most full-height sections, svh gives the least surprising result on a phone. Test all of them in a device emulator with the browser bar shown and hidden.
Next: Flexbox. To learn CSS from the ground up with a mentor, Ampersand Academy teaches web development one-to-one.
Frequently asked questions
What is the best CSS colour format?
Any of them work. Hex is compact for fixed values, rgb and hsl are readable, and oklch is worth using when you want perceptually even lightness across a palette.
What does color-mix() do in CSS?
It blends two colours by a given percentage so you can derive lighter and darker shades from a base colour instead of hard-coding every variant.
Should I use rem or px for font sizes?
Use rem for text and spacing. Because rem is relative to the root font size, the layout scales when a user increases their browser text size, which is an accessibility win.
What is the difference between dvh, svh and lvh?
They describe mobile viewport heights. svh is the smallest, with browser bars visible and stable; lvh is the largest, as if the bars were gone; dvh follows the bars as they move.
How do I set a comfortable line length in CSS?
Cap the width with ch units, which measure the width of the 0 character. A value around 65ch gives the 60 to 75 character line that is easiest to read.
Last updated on · Written by Dinesh Kumar R

