Home Module 03 Units

1. Introduction

Whenever you set a size in CSS — whether it is a font size, a width, a margin, or padding — you need to specify a unit. Writing font-size: 16 with no unit does not work. You must write font-size: 16px or font-size: 1rem.

CSS has many units, and choosing the right one matters. Some units are absolute (always the same size, like px). Others are relative (their size depends on something else, like em and %).

Understanding units is essential for building responsive layouts — pages that look good on mobile phones as well as large desktop screens.

2. Theory

Absolute Units

These have a fixed physical size and do not change based on anything else.

UnitNameUse case
pxPixelsMost common — borders, precise sizing, layout
ptPointsPrint stylesheets (avoid for screens)
cm, mmCentimetres, MillimetresPrint only

On screen, px (pixels) is the only absolute unit you will regularly use.

Relative Units

These scale based on another value.

UnitRelative toUse case
emCurrent element's font-sizePadding/margin relative to text size
remRoot element's font-size (<html>)Font sizes — consistent scaling
%Parent element's sizeWidths, fluid layouts
vw1% of the viewport widthFull-width elements, fluid text
vh1% of the viewport heightFull-height sections, hero areas
vmin1% of the smaller viewport dimensionResponsive elements
vmax1% of the larger viewport dimensionRare usage
chWidth of the "0" characterText containers (e.g. max-width: 65ch)

px — Pixels

The most familiar unit. 1px on a screen is a display pixel. Note: on high-DPI screens (Retina), 1 CSS pixel = 2+ physical pixels, but the browser handles this automatically.

border: 1px solid #ccc;
padding: 16px;
width: 300px;

Good for: borders, shadows, precise fixed widths, small spacings. Avoid for font sizes (makes user preferences irrelevant).

em — Relative to Current Font Size

If the current element's font-size is 16px, then 1em = 16px, 2em = 32px, 0.5em = 8px.

p {
  font-size: 16px;
  padding: 1em;    /* = 16px (same as font-size) */
  margin: 1.5em;   /* = 24px */
}

Problem with em: It compounds. If a parent is 2em and a child is also 2em, the child ends up 4em of the root — this is confusing.

rem — Relative to Root Font Size

rem always refers to the <html> element's font size (default: 16px in most browsers). It does NOT compound. This makes rem the preferred unit for font sizes.

html { font-size: 16px; } /* or just leave it default */

h1 { font-size: 2rem; }   /* always 32px */
h2 { font-size: 1.5rem; } /* always 24px */
p  { font-size: 1rem; }   /* always 16px */

% — Percentage

Relative to the parent element's corresponding property.

.container { width: 800px; }
.sidebar   { width: 25%; }  /* = 200px (25% of 800px) */
.main      { width: 75%; }  /* = 600px */

/* For height, parent must have explicit height */
.hero { height: 100vh; } /* full viewport height — safer for full-screen */

vw and vh — Viewport Units

The viewport is the visible browser window. 100vw = 100% of the window width; 100vh = 100% of the window height.

.hero {
  width: 100vw;   /* full window width */
  height: 100vh;  /* full window height */
}

.sidebar {
  height: 100vh;  /* sidebar that fills the screen height */
}

/* Fluid font size */
h1 { font-size: clamp(1.5rem, 4vw, 3rem); }

clamp() — Responsive Sizing

clamp(min, preferred, max) lets you set a minimum size, a preferred fluid size, and a maximum. This creates responsive sizing without media queries.

font-size: clamp(1rem, 2.5vw, 2rem);
/* minimum: 1rem (16px)
   preferred: 2.5% of viewport width
   maximum: 2rem (32px) */

3. Real World Example

A typical professional CSS file uses different units for different purposes:

  • px: border: 1px solid #ccc;, border-radius: 8px;
  • rem: font-size: 1.125rem;, margin-bottom: 1.5rem;
  • %: width: 100%;, max-width: 1200px;
  • vh: min-height: 100vh; on the page wrapper
  • ch: max-width: 65ch; on article text for ideal reading line length
  • clamp(): font-size: clamp(1rem, 2vw, 1.5rem); for fluid headings

4. Code Example

/* ===== UNIT EXAMPLES ===== */

/* Root font size — basis for rem */
html {
  font-size: 16px; /* 1rem = 16px */
}

/* Typography — use rem */
h1 { font-size: 2.5rem; }   /* 40px */
h2 { font-size: 2rem; }     /* 32px */
h3 { font-size: 1.5rem; }   /* 24px */
p  { font-size: 1rem; }     /* 16px */
small { font-size: 0.875rem; } /* 14px */

/* Spacing — use rem for consistency */
.card {
  padding: 1.5rem;  /* 24px */
  margin-bottom: 2rem; /* 32px */
  border-radius: 8px;  /* px for small precise values */
  border: 1px solid #e2e8f0; /* px for borders */
}

/* Layout — use % for fluid widths */
.container {
  width: 90%;
  max-width: 1200px;
  margin: 0 auto;
}

/* Full-screen hero */
.hero {
  width: 100%;
  min-height: 100vh;
  display: flex;
  align-items: center;
}

/* Sidebar */
.sidebar {
  width: 280px;  /* fixed px for sidebar */
  height: 100vh;
}

/* Fluid font with clamp */
.hero-title {
  font-size: clamp(1.75rem, 5vw, 4rem);
}

/* Readable line length */
.article-body {
  max-width: 65ch;
  line-height: 1.7;
}

5. Code Breakdown

font-size: 2.5rem on h1
With root at 16px, this equals 40px. If a user has set their browser default to 20px for accessibility, this scales to 50px automatically — respecting the user's preference. This is why rem is better than px for fonts.
width: 90%; max-width: 1200px;
A classic fluid layout pattern. On small screens (360px wide): 90% = 324px. On large screens (1400px wide): 90% = 1260px, but max-width caps it at 1200px. The content never gets too wide to read comfortably.
margin: 0 auto
The shorthand 0 auto means top/bottom margin = 0, left/right margin = auto. Auto margins distribute equally on both sides — this horizontally centres the element inside its parent.
min-height: 100vh
Using min-height instead of height allows content to grow beyond the viewport if needed. height: 100vh would clip overflowing content.
max-width: 65ch
The ch unit equals the width of the "0" character in the current font. 65ch = approximately 65 characters wide — typography research shows this is the optimal line length for reading.

6. Common Mistakes

  • Using px for all font sizes. Pixel font sizes ignore browser text-size preferences and hurt accessibility. Use rem for font sizes.
  • Confusing em and rem. em is relative to the current element — it compounds and becomes unpredictable in nested elements. rem always refers to the root — far more predictable.
  • Setting height: 100% without a parent height. Percentage heights only work if the parent has an explicit height set. Use height: 100vh for full-screen instead.
  • Forgetting units entirely. margin: 16 (without px) will be ignored by the browser — except for line-height which uniquely accepts unitless values.
  • Using vw for widths causing horizontal scroll. 100vw includes the scrollbar width on some browsers, causing a tiny horizontal scroll. Use width: 100% for full-width elements instead.

7. Best Practices

  • Use rem for all font sizes — respects user accessibility preferences and scales consistently.
  • Use px for borders, shadows, and small precise measurements — these should not scale with font size.
  • Use % or vw for widths — fluid layouts that adapt to screen size.
  • Use vh for full-screen sections — hero areas, full-page modals, sidebars.
  • Use clamp() for responsive typography — fluid sizing without media queries.
  • Set html { font-size: 16px; } explicitly or rely on browser default — do NOT set it to a percentage like 62.5% (old trick that breaks accessibility).
  • Use max-width: 65ch on article/blog body text for optimal readability.

8. Practice Exercise

Create units.html and units.css. Build a page that demonstrates each unit:

  1. Set up a heading scale using rem: h1=2.5rem, h2=2rem, h3=1.5rem, p=1rem
  2. Create a .container that is 90% wide with a max-width of 900px, centred with auto margins
  3. Create a hero section with min-height: 100vh and a gradient background
  4. Create two columns inside a container: left 30% wide, right 70% wide (using %)
  5. Add a card with padding of 1.5rem and a border of 1px
  6. Resize the browser window — notice how % widths adapt but px values stay fixed

9. Assignment

Build a full-page landing page layout using the right units throughout:

  • A hero section with 100vh height, centred text, and a fluid heading using clamp()
  • A features section with three cards side by side, each taking 33.33% width with a max-width container
  • All font sizes in rem
  • All spacing (padding, margin) in rem
  • All borders in px
  • Article text limited to 65ch max-width

10. Interview Questions

Q1: What is the difference between px, em, and rem?

Answer: px is an absolute pixel unit that never changes. em is relative to the current element's font-size — it compounds in nested elements. rem is always relative to the root element's font-size, so it is consistent and predictable.

Q2: Why should you use rem instead of px for font sizes?

Answer: Using rem respects the user's browser font size preferences (important for accessibility). If a user increases their browser's default font size for readability, rem values scale up accordingly while px values ignore this setting.

Q3: What is the difference between vh and %?

Answer: vh is relative to the viewport (browser window) height. % is relative to the parent element. For full-screen heights, 100vh is reliable; 100% only works if every ancestor has an explicit height set.

Q4: What does clamp() do?

Answer: clamp(min, preferred, max) returns the preferred value, but never below the minimum or above the maximum. It is useful for responsive typography — text grows as the viewport widens but never gets too small or too large.

Q5: What units would you use for padding?

Answer: It depends. rem is common and scales with font size. px is fine for small fixed spacings like border: 1px. Avoid em for padding unless you intentionally want it to scale with the element's font size. Some developers use rem exclusively for all spacing for consistency.

11. Additional Resources

  • MDN Web Docs — CSS Values and Units (search "MDN CSS values and units")
  • CSS-Tricks — The Lengths of CSS (search "css-tricks lengths of css")
  • MDN — clamp() function (search "MDN clamp CSS")
  • Every Layout — Intrinsic Web Design (search "every layout intrinsic design")
  • Josh Comeau — The Surprising Truth About Pixels and Accessibility (search this title)