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:
.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:
/* 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:
/* 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:
/* 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:
/* 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:
/* 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:
/* 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:
/* 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:
/* 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 â
/* 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 â
/* 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:
/* 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:
.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:
.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:
/* 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 â
: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 â
/* 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 â
/* 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) â
/* 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 Case | Recommended Unit | Reason |
|---|---|---|
| Font Size | rem | Global consistency, easy responsiveness |
| Small Padding | px | Precise detail control |
| Large Padding | rem | Maintains overall proportion |
| Width | %, vw, fr | Responsive layout |
| Max Width | px, rem | Limit extremes |
| Border | px | Pixel precision |
| Shadow | px | Precise control |
| Line Height | Unitless number | Multiple of font size |
| Media Queries | em, px | Consistent breakpoints |
| Animation | s, ms | Time 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 effectrem- 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 heightvmin,vmax- Viewport minimum/maximum valueslvh,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