CSS Colors and Units: Hex, RGB, Rem, Em, and Viewport Units
CSS color formats are different recipes for mixing the same paint, while each CSS unit tells the browser which reference to measure from. Start with the syntax below, then choose a format or unit whose reference is clear to the next person reading the rule.
.notice {
color: hsl(222 47% 11%);
background: rgb(219 234 254 / 80%);
border: 1px solid #93c5fd;
padding: 1rem;
width: 80%;
} The notice uses HSL for opaque text, RGB with an alpha channel for a translucent background, hex for a compact border color, rem for root-relative spacing, and a percentage width tied to its parent.
CSS Color and Unit Syntax
A color value can be a keyword, a hexadecimal string, or a function. Modern rgb() and hsl() syntax separates channels with spaces. If the color needs transparency, a slash separates the three color channels from the optional alpha value.
Lengths combine a number with a unit, such as 16px, 1rem, or 40vw. A percentage is resolved against a property-specific reference. For example, width: 50% uses the containing block's width, while font-size: 120% uses the parent's font size.
Color Keywords
Named colors make early examples easy to read because their meaning is visible in the declaration. CSS defines keywords such as tomato, rebeccapurple, and transparent, but a product palette usually needs more precise values than names provide.
.status {
color: navy;
background: lightyellow;
border-color: tomato;
} Use keywords for learning, quick prototypes, and familiar values such as transparent. Use a numeric format when a design requires an exact shade.
Hex Colors
Hex writes the paint recipe as compact red, green, and blue hexadecimal pairs after #. The six-digit value #2563eb copies cleanly from design tools. Three-digit shorthand works only when every pair repeats, so #fff expands to #ffffff.
.button {
color: #ffffff;
background: #2563eb;
border-color: #1d4ed8;
} An eight-digit hex value adds an alpha pair at the end. The eight-digit example #2563eb80 uses approximately 50% opacity. The compact form is valid, but the alpha pair is less obvious than slash-alpha syntax during review.
RGB Colors and Slash Alpha
rgb() spells out the same paint recipe through red, green, and blue channels written as numbers from 0 to 255 or percentages from 0% to 100%. Modern syntax uses spaces between channels, then an optional slash followed by a number or percentage for alpha.
.overlay {
background: rgb(15 23 42 / 70%);
}
.overlay-light {
background: rgb(15 23 42 / 0.25);
} The first background is 70% opaque, and the second is 25% opaque. This syntax is a good fit when a color comes from RGB channel values or when transparency needs to remain immediately visible.
HSL Colors and Slash Alpha
The hsl() paint recipe uses hue, saturation, and lightness. Hue moves around a color wheel, saturation controls color intensity, and lightness moves from black through the chosen color to white. Keeping hue and saturation steady makes related light and dark variants easier to edit by hand.
.tag {
background: hsl(217 91% 60%);
}
.tag-soft {
background: hsl(217 91% 85% / 80%);
} The slash before 80% performs the same alpha job as it does in rgb(). Both functions use the modern space-separated form, so the color channels stay visually separate from opacity.
When Each Color Format Fits
| Format | Best fit |
|---|---|
| Keyword | Readable examples, prototypes, and familiar special values. |
| Hex | Compact opaque colors copied from a design specification. |
rgb() | RGB channel values and clearly written transparency. |
hsl() | Related shades adjusted through hue, saturation, or lightness. |
How CSS Length Units Work
Once the paint recipe is chosen, each length still needs a measuring reference. The unit names that reference, so two equal numbers can produce different sizes when their units point to different places.
pxis an absolute CSS length suited to thin borders and small fixed details.remuses the root element's font size, which makes it a steady choice for type and spacing.emonfont-sizeuses the parent's font size; on most other properties, it uses the element's own font size.%uses a reference defined by the property, often the parent or containing block.vwequals 1% of the viewport width and suits dimensions that intentionally track the screen.
Worked Card Example
.card {
width: 80%;
max-width: 40rem;
padding: 1.5rem;
border: 1px solid #93c5fd;
color: hsl(222 47% 11%);
background: rgb(219 234 254 / 80%);
}
.card__title {
margin-bottom: 0.5em;
font-size: 1.5rem;
} With a 16px root size, the card's 1.5rem padding computes to 24px and the title's 1.5rem size also computes to 24px. The title's 0.5em bottom margin then computes from that local 24px font size, producing 12px. The percentage width follows the parent, while max-width stops the card from growing indefinitely.
Common Pitfalls & Debugging
em Values Compound Through Nesting
Symptom: nested text gets larger at every level. Cause: each element uses an em font size calculated from its parent's already enlarged value. Fix: use rem when every level should share one root-based size.
.menu {
font-size: 1.2em;
}
/* Fix: rem replaces the compounding em. */
.menu .menu {
font-size: 1rem;
} Hex Alpha Is Easy to Misread
Symptom: an eight-digit hex color has unexpected opacity. Cause: its final pair encodes alpha in hexadecimal, so 80 means about 50%, not 80%. Fix: use slash-alpha RGB or HSL when reviewers need to read transparency directly.
Mixed Units Hide the Scaling Rule
Symptom: related spacing changes at different rates. Cause: the component mixes root-relative, local-font, parent, and viewport references without a reason. Fix: choose units by job, document exceptions, and keep related values on the same scale.
Conclusion
Choose a color recipe that makes its channels readable, then choose each unit from the reference the property should follow. Consistent choices make later edits easier to predict.
Frequently Asked Questions
Is a CSS pixel one device pixel?
A CSS pixel is a reference unit rather than a guaranteed physical screen dot. High-density screens can use several device pixels to render one CSS pixel, and browser zoom can scale dimensions written in px.
Can one calc expression mix units?
Yes, that is what it is for. Subtracting a rem value from a percentage resolves both against their own references before combining, which is the standard way to leave fixed space beside a proportional dimension.
What does one rem equal?
One rem equals the computed font size of the root element. Browsers commonly begin with a 16px default, but readers can change that setting, so rem-based text and spacing can scale with their preference.
Should layout widths use percent or vw?
Use percentages when an element should scale with its containing block. Use vw when it should scale with the viewport itself, and add a maximum width when an unrestricted viewport value could make content too wide.
Can CSS custom properties store colour values for reuse across a stylesheet?
Yes. Declare a custom property such as --brand-color on :root or a component's class, then reference it with var(--brand-color) anywhere that colour is needed. Changing the single declaration updates every rule that reads it, which keeps a scheme consistent without a preprocessor.
Related Typography and Color Guides
- Return to the CSS typography and color guide.
- Store repeated values with CSS custom properties.
- Apply these units to CSS fonts and text.
- Reuse slash-alpha colors in the CSS shadows guide.
Sources
-
[1]
CSS color values(developer.mozilla.org)
-
[2]
<length> CSS data type(developer.mozilla.org)
-
[3]
CSS values and units(developer.mozilla.org)
Read Next
Style readable text with font-family stacks, size, unitless line height, weight, spacing, web-font fallbacks, and text wrapping.
Define reusable CSS values with custom properties, var() fallbacks, scoped overrides, theme switching, and computed-value debugging.
Learn CSS typography and color through color formats, length units, font and text properties, custom properties, and shadows.