Skip to content

CSS Unit System: The Language Art of Sizing

The Essence of Units

In CSS, almost all sizes and distances require units. Choosing the correct unit not only affects the visual appearance of a page but also determines a website's responsive capability and maintainability.

CSS units can be divided into two main categories:

  • Absolute Units: Fixed physical sizes
  • Relative Units: Sizes relative to other elements or context

Understanding the characteristics and applicable scenarios of each unit type is key to mastering CSS layout.

Absolute Units

Absolute units have fixed sizes that don't change with context.

px (Pixels)

Pixels are the most commonly used absolute unit, representing a single physical pixel on screen:

css
.box {
  width: 200px;
  height: 100px;
  font-size: 16px;
  border: 1px solid #ddd;
}

Characteristics:

  • Precise size control
  • Maintains the same visual size across different devices (with the same device pixel ratio)
  • Not affected by parent elements

Applicable Scenarios:

  • Border width: border: 1px solid #ddd
  • Shadow offset: box-shadow: 2px 4px 8px rgba(0,0,0,0.1)
  • Small icon sizes: width: 24px; height: 24px
  • Media query breakpoints: @media (min-width: 768px)

Considerations:

css
/* Pixel density issues on modern devices */
/* iPhone's physical resolution is 750x1334, but CSS pixels are 375x667 */
/* This is because the Device Pixel Ratio (DPR) is 2 */

.icon {
  width: 20px; /* Takes up 40 physical pixels on high-DPI screens */
}

/* Mobile adaptation */
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 2dppx) {
  .retina-image {
    background-image: url("[email protected]");
    background-size: 100px 100px; /* Half the original size */
  }
}

Other Absolute Units

These units are primarily used for print styles:

css
/* Rarely used for screen display */
.print-content {
  width: 21cm; /* Centimeters */
  height: 29.7cm; /* A4 paper size */
  margin: 2.54cm; /* 1 inch = 2.54cm */
  font-size: 12pt; /* Points, 1pt = 1/72 inch */
  line-height: 1pc; /* Pica, 1pc = 12pt */
}

@media print {
  body {
    width: 210mm; /* Millimeters */
    margin: 1in; /* Inches */
  }

  h1 {
    font-size: 18pt; /* pt is more precise for printing */
  }
}

Relative Units

Relative units depend on other elements or context, making them particularly suitable for responsive design.

em - Relative to Parent Element

em is relative to the font-size of the current element. If the current element doesn't have a font-size set, it's relative to the parent element's font-size:

css
/* Basic example */
.parent {
  font-size: 16px;
}

.child {
  font-size: 1.5em; /* 16px × 1.5 = 24px */
  padding: 1em; /* 24px × 1 = 24px (relative to own font-size) */
  margin: 0.5em; /* 24px × 0.5 = 12px */
}

/* Compound effect of em */
.level-1 {
  font-size: 1.2em; /* Assuming parent is 16px, this is 19.2px */
}

.level-1 .level-2 {
  font-size: 1.2em; /* 19.2px × 1.2 = 23.04px */
}

.level-1 .level-2 .level-3 {
  font-size: 1.2em; /* 23.04px × 1.2 = 27.65px */
}
/* Nesting causes fonts to get progressively larger or smaller */

Practical Applications:

css
/* Create modular components */
.button {
  font-size: 16px; /* Base size */
  padding: 0.5em 1em; /* 8px 16px */
  border-radius: 0.25em; /* 4px */
  margin: 0.5em; /* 8px */
}

.button-large {
  font-size: 20px; /* Change base */
  /* padding automatically becomes 10px 20px */
  /* border-radius automatically becomes 5px */
  /* margin automatically becomes 10px */
}

.button-small {
  font-size: 12px;
  /* All sizes scale proportionally */
}

/* Responsive typography */
h1 {
  font-size: 2em; /* Relative to parent element */
  margin-bottom: 0.5em; /* Maintains proportion */
  line-height: 1.2em; /* Relative to self */
}

rem - Relative to Root Element

rem (root em) is relative to the font-size of the root element (<html>), avoiding the compound effect of em:

css
/* Set root element base */
html {
  font-size: 16px; /* 1rem = 16px */
}

.container {
  padding: 1rem; /* 16px */
  margin-bottom: 2rem; /* 32px */
}

.title {
  font-size: 2rem; /* 32px */
  margin-bottom: 1rem; /* 16px */
}

.nested .deeply .buried .text {
  font-size: 1rem; /* Always 16px, not affected by nesting */
}

Responsive Design:

css
/* Responsive system based on root font size */
html {
  font-size: 16px;
}

@media (max-width: 768px) {
  html {
    font-size: 14px; /* All elements using rem automatically scale down proportionally */
  }
}

@media (max-width: 480px) {
  html {
    font-size: 12px;
  }
}

/* All sizes automatically adapt */
.card {
  padding: 1.5rem; /* Tablet: 21px, Mobile: 18px */
  border-radius: 0.5rem; /* Tablet: 7px, Mobile: 6px */
}

.heading {
  font-size: 2.5rem; /* Tablet: 35px, Mobile: 30px */
  margin-bottom: 1rem; /* Tablet: 14px, Mobile: 12px */
}

Usage Tip: 62.5% Base:

css
/* Calculation convenience trick */
html {
  font-size: 62.5%; /* 16px × 62.5% = 10px */
}

body {
  font-size: 1.6rem; /* 16px */
}

.text-small {
  font-size: 1.2rem; /* 12px */
}

.text-large {
  font-size: 2rem; /* 20px */
}

.heading {
  font-size: 3.2rem; /* 32px */
}

% - Percentage

Percentage units are relative to the corresponding property value of the parent element:

css
/* Width percentage */
.container {
  width: 100%; /* 100% of parent element width */
  max-width: 1200px; /* Limit maximum width */
}

.column {
  width: 50%; /* 50% of parent element width */
  padding: 2%; /* 2% of parent element width */
}

/* Height percentage - requires parent element to have explicit height */
.parent {
  height: 500px; /* Must set height */
}

.child {
  height: 80%; /* 500px × 80% = 400px */
}

/* padding and margin percentages are both relative to parent element's width */
.box {
  width: 100%;
  padding-bottom: 56.25%; /* 16:9 aspect ratio (9/16 = 0.5625) */
}

/* Percentages in position */
.centered {
  position: absolute;
  top: 50%; /* Relative to parent element height */
  left: 50%; /* Relative to parent element width */
  transform: translate(-50%, -50%); /* Relative to own size */
}

/* Percentages in transform are relative to element itself */
.slide-in {
  transform: translateX(-100%); /* Move left by own width */
}

/* background-position percentages */
.banner {
  background-position: 50% 50%; /* Center horizontally and vertically */
}

Viewport Units

Viewport units are relative to the browser viewport's size.

vw and vh

css
/* vw: 1vw = 1% of viewport width */
/* vh: 1vh = 1% of viewport height */

/* Full screen section */
.hero {
  width: 100vw; /* 100% of viewport width */
  height: 100vh; /* 100% of viewport height */
}

/* Responsive text */
.title {
  font-size: 5vw; /* 60px on a 1200px wide screen */
  /* 18.75px on a 375px wide mobile */
}

/* Limit range */
.responsive-text {
  font-size: clamp(16px, 4vw, 48px);
  /* Minimum 16px, ideal 4vw, maximum 48px */
}

/* Fixed aspect ratio container */
.video-container {
  width: 80vw;
  height: 45vw; /* 16:9 ratio (80 × 9/16 = 45) */
  max-width: 1200px;
  max-height: 675px;
}

vmin and vmax

css
/* vmin: 1% of the smaller of viewport width and height */
/* vmax: 1% of the larger of viewport width and height */

/* Element visible in any orientation */
.square {
  width: 50vmin; /* Never exceeds half the viewport */
  height: 50vmin;
}

/* Responsive icon */
.icon {
  font-size: 10vmin; /* Maintains appropriate size in landscape and portrait */
}

/* Full screen background */
.background {
  width: 100vmax;
  height: 100vmax;
}

lvh, svh, dvh - Mobile Viewport Units

New CSS viewport units that solve mobile address bar issues:

css
/* lvh (Large Viewport Height): height excluding address bar */
/* svh (Small Viewport Height): height including address bar */
/* dvh (Dynamic Viewport Height): dynamic height */

.mobile-hero {
  height: 100dvh; /* Dynamically adapts to address bar show/hide */
}

.fixed-header {
  height: 100svh; /* Uses minimum viewport height */
}

.content {
  min-height: 100lvh; /* Uses maximum viewport height */
}

Angle Units

Used for transform and gradient:

css
.rotated {
  transform: rotate(45deg); /* Degrees (0-360) */
  transform: rotate(0.785rad); /* Radians */
  transform: rotate(50grad); /* Gradians (0-400) */
  transform: rotate(0.125turn); /* Turns */
}

.gradient {
  background: linear-gradient(135deg, blue, red);
}

Time Units

Used for animations and transitions:

css
.transition {
  transition: all 0.3s ease; /* Seconds */
  transition: all 300ms ease; /* Milliseconds */
}

.animation {
  animation: slide 2s ease-in-out; /* 2 seconds */
  animation-delay: 500ms; /* 500 millisecond delay */
}

calc() Function

Mix different units:

css
/* Basic calculations */
.container {
  width: calc(100% - 80px); /* Percentage minus fixed value */
  padding: calc(2rem + 10px); /* rem plus px */
  margin: calc(5vw - 20px); /* Viewport unit minus px */
}

/* Complex layout */
.sidebar {
  width: 300px;
}

.main-content {
  width: calc(100% - 300px); /* Remaining width */
}

/* Responsive spacing */
.grid {
  grid-template-columns: repeat(3, calc((100% - 40px) / 3));
  gap: 20px;
}

/* Dynamic font size */
.fluid-text {
  font-size: calc(16px + 1vw); /* Base size + viewport scaling */
}

/* Nested calc */
.complex {
  width: calc(100% - calc(20px * 2));
}

Practical Techniques

Responsive Typography System

css
:root {
  --base-size: 16px;
  --scale-ratio: 1.25;

  --text-xs: calc(var(--base-size) / var(--scale-ratio) / var(--scale-ratio));
  --text-sm: calc(var(--base-size) / var(--scale-ratio));
  --text-base: var(--base-size);
  --text-lg: calc(var(--base-size) * var(--scale-ratio));
  --text-xl: calc(var(--base-size) * var(--scale-ratio) * var(--scale-ratio));
  --text-2xl: calc(
    var(--base-size) * var(--scale-ratio) * var(--scale-ratio) * var(--scale-ratio)
  );
}

.text-xs {
  font-size: var(--text-xs);
} /* ~10px */
.text-sm {
  font-size: var(--text-sm);
} /* ~13px */
.text-base {
  font-size: var(--text-base);
} /* 16px */
.text-lg {
  font-size: var(--text-lg);
} /* ~20px */
.text-xl {
  font-size: var(--text-xl);
} /* ~25px */
.text-2xl {
  font-size: var(--text-2xl);
} /* ~31px */

Perfect Square

css
/* Create square using padding-bottom */
.square {
  width: 100%;
  padding-bottom: 100%; /* Relative to width */
  position: relative;
  background: blue;
}

.square-content {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

/* Using aspect-ratio (modern browsers) */
.modern-square {
  width: 100%;
  aspect-ratio: 1 / 1;
}

.video-16-9 {
  width: 100%;
  aspect-ratio: 16 / 9;
}

Fluid Typography

css
/* Implement fluid text size using clamp */
h1 {
  font-size: clamp(2rem, 5vw, 4rem);
  /* Minimum 2rem, ideal 5vw, maximum 4rem */
}

p {
  font-size: clamp(1rem, 1vw + 0.5rem, 1.5rem);
}

/* Fluid spacing */
.section {
  padding: clamp(2rem, 5vw, 5rem) clamp(1rem, 3vw, 3rem);
}

Container Query Units (Experimental)

css
/* Units based on container */
.card {
  container-type: inline-size;
}

.card-title {
  font-size: 5cqw; /* Container Query Width */
}

.card-content {
  padding: 2cqh; /* Container Query Height */
}

Unit Selection Guide

Use CaseRecommended UnitReason
Font SizeremGlobal consistency, easy responsiveness
Small PaddingpxPrecise detail control
Large PaddingremMaintains overall proportion
Width%, vw, frResponsive layout
Max Widthpx, remLimit extremes
BorderpxPixel precision
ShadowpxPrecise control
Line HeightUnitless numberMultiple of font size
Media Queriesem, pxConsistent breakpoints
Animations, msTime control

Summary

Choosing appropriate CSS units is fundamental to building responsive, maintainable websites. There's no absolute best unit; the key is understanding the characteristics of each unit and making informed choices based on specific scenarios.

Key Points:

  • Absolute Units: Fixed size, not affected by context
    • px - Most commonly used, precise control
    • Print units (cm, mm, in, pt, pc) - Mainly for print styles
  • Relative Units: Size relative to other elements or context
    • em - Relative to parent element, has compound effect
    • rem - Relative to root element, no compound effect, recommended for global use
    • % - Relative to parent element's corresponding property
  • Viewport Units: Relative to browser viewport
    • vw, vh - Viewport width and height
    • vmin, vmax - Viewport minimum/maximum values
    • lvh, svh, dvh - Mobile viewport units
  • Other Units: Angles (deg, rad), time (s, ms)
  • calc() Function: Mix different units for calculations
  • Practical Techniques: Responsive typography, perfect squares, fluid typography, container queries
  • Selection Guide: Choose the most appropriate unit based on use case