CSS Tutorial
CSS Units
CSS lengths can be written in many units, and choosing the right one is key to responsive, accessible design. Units split into two families: absolute units like px that stay fixed, and relative units like em, rem, %, vw, and vh that scale with context. This guide explains each unit and when to reach for it.
Absolute vs Relative Units
Absolute units are fixed sizes that never change - the pixel (px) is the one you will use most. Relative units are calculated from something else: a font size, a parent element, or the viewport. Relative units adapt to different screens and user settings, which is why modern responsive design leans on them heavily.
| Unit | Relative to | Typical use |
|---|---|---|
| px | Nothing (absolute) | Borders, fine details, fixed sizes |
| em | Font size of the element (or its parent) | Padding/margins that scale with text |
| rem | Font size of the root <html> element | Consistent, scalable sizing across the page |
| % | The parent element's size | Fluid widths and layouts |
| vw | 1% of the viewport width | Full-width heroes, fluid type |
| vh | 1% of the viewport height | Full-height sections |
px - The Absolute Pixel
One px is a single device-independent pixel. It is predictable and precise, which makes it ideal for hairline borders and details that should not scale. Its downside is that px sizes ignore the user's browser font-size preference, so using px for body text can hurt accessibility.
.card { border: 1px solid #ccc; border-radius: 8px; }em and rem - Font-Relative Units
1em equals the current element's font size, so 2em is twice the text size. Because em compounds through nested elements, it can be tricky. rem sidesteps that by always referring to the root font size (the html element, usually 16px), giving you predictable scaling everywhere. Set your root font size once and the whole page scales from it.
<!DOCTYPE html>
<html>
<head>
<style>
html { font-size: 16px; }
.a { font-size: 1rem; } /* 16px */
.b { font-size: 1.5rem; } /* 24px */
.c { font-size: 2rem; } /* 32px */
div { font-family: system-ui, sans-serif; padding: 6px 0; }
</style>
</head>
<body>
<div class="a">1rem text (16px)</div>
<div class="b">1.5rem text (24px)</div>
<div class="c">2rem text (32px)</div>
</body>
</html>Prefer rem for font sizes so text respects the user's browser zoom and font-size settings. Reserve px for things that truly should stay fixed, like a 1px border.
Percent - Relative to the Parent
A percentage is measured against the parent element. width: 50% means half the parent's width. Percentages power fluid layouts where columns grow and shrink with the container.
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: system-ui, sans-serif; padding: 16px; }
.bar { background: #e2e8f0; border-radius: 6px; margin: 6px 0; }
.fill { background: #0f766e; color: #fff; padding: 8px; border-radius: 6px; font-size: 13px; }
.w25 { width: 25%; } .w50 { width: 50%; } .w100 { width: 100%; box-sizing: border-box; }
</style>
</head>
<body>
<div class="bar"><div class="fill w25">25%</div></div>
<div class="bar"><div class="fill w50">50%</div></div>
<div class="bar"><div class="fill w100">100%</div></div>
</body>
</html>vw and vh - Viewport Units
Viewport units scale with the browser window itself. 1vw is 1% of the viewport width and 1vh is 1% of its height, so height: 100vh fills the entire visible screen no matter the device. They are great for full-screen hero sections and fluid typography.
<!DOCTYPE html>
<html>
<head>
<style>
body { margin: 0; font-family: system-ui, sans-serif; }
.hero { height: 40vh; display: flex; align-items: center; justify-content: center; background: linear-gradient(135deg, #0f766e, #14b8a6); color: #fff; font-size: 4vw; font-weight: bold; }
</style>
</head>
<body>
<div class="hero">40vh tall, 4vw text</div>
<p style="padding:16px;">Resize the frame - the hero height and text scale with the viewport.</p>
</body>
</html>Avoid setting font sizes in pure vw with no floor - text can shrink to unreadable on small screens. Combine viewport units with clamp() so type stays within a sensible range.
Key points
- px is absolute and fixed; use it for borders and fine details.
- rem scales from the root font size and is the safest choice for text and spacing.
- em is relative to the element's own font size and compounds when nested.
- % is relative to the parent element, ideal for fluid widths.
- vw and vh scale with the viewport - great for full-screen sections and fluid type.
