font-family – Choosing the Typeface
font-family sets the typeface. You provide a comma-separated list of font names — the browser uses the first one that is available on the user's device. The last item should always be a generic family (serif, sans-serif, monospace, cursive, fantasy) as a final fallback.
/* Font stack — browser tries each in order */
body {
font-family: 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}
/* Serif font stack */
.article-body {
font-family: Georgia, 'Times New Roman', Times, serif;
}
/* Monospace for code */
code, pre {
font-family: 'Cascadia Code', 'Fira Code', Consolas, 'Courier New', monospace;
}
/* Multi-word font names must be quoted */
h1 { font-family: 'Open Sans', sans-serif; }
Web-Safe Fonts
Web-safe fonts are installed on virtually every device — you can use them without loading anything:
/* Sans-serif */
font-family: Arial, sans-serif;
font-family: 'Helvetica Neue', Helvetica, sans-serif;
font-family: 'Segoe UI', sans-serif; /* Windows system font */
font-family: -apple-system, sans-serif; /* macOS system font */
/* Serif */
font-family: Georgia, serif;
font-family: 'Times New Roman', Times, serif;
/* Monospace */
font-family: Consolas, 'Courier New', monospace;
font-family: 'Lucida Console', monospace;
/* System font stack (recommended for performance) */
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI',
Roboto, Oxygen, Ubuntu, sans-serif;
Loading Google Fonts
Google Fonts provides 1,500+ free fonts. Add the <link> in your HTML <head>, then use the font name in CSS:
<head>
<!-- Preconnect for performance -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<!-- The font itself -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&family=Playfair+Display:wght@700&display=swap" rel="stylesheet">
</head>
body { font-family: 'Inter', sans-serif; }
h1, h2 { font-family: 'Playfair Display', serif; }
font-size – Setting Text Size
/* Absolute — px is most predictable */
p { font-size: 16px; }
h1 { font-size: 48px; }
/* Relative to root font size — best for accessibility */
/* (root = <html> font-size, usually 16px) */
p { font-size: 1rem; } /* 16px */
h1 { font-size: 3rem; } /* 48px */
small { font-size: 0.875rem; } /* 14px */
/* Relative to parent font size */
.card p { font-size: 1.1em; } /* 10% bigger than parent */
/* Viewport-relative — scales with screen width */
h1 { font-size: clamp(1.8rem, 5vw, 3.5rem); }
/* clamp(min, preferred, max) — responsive without media queries */
/* Named sizes (less precise, avoid in production) */
font-size: small;
font-size: medium;
font-size: large;
font-size: x-large;
Set font-size: 16px on html (or leave it default), then use rem everywhere else. This respects the user's browser font size preferences (accessibility). Use clamp() for headings to get fluid responsive type without media queries.
font-weight – Bold and Thin
/* Numeric values (100–900, increments of 100) */
font-weight: 100; /* Thin */
font-weight: 300; /* Light */
font-weight: 400; /* Regular (normal) */
font-weight: 500; /* Medium */
font-weight: 600; /* SemiBold */
font-weight: 700; /* Bold */
font-weight: 800; /* ExtraBold */
font-weight: 900; /* Black */
/* Keywords */
font-weight: normal; /* = 400 */
font-weight: bold; /* = 700 */
font-weight: lighter; /* one step lighter than parent */
font-weight: bolder; /* one step bolder than parent */
font-style and font-variant
/* Italic */
em, .italic { font-style: italic; }
cite { font-style: italic; }
/* Remove italic from something that's italic by default */
.not-italic { font-style: normal; }
/* Small caps — uppercase letters displayed at small-cap size */
.byline { font-variant: small-caps; }
/* Numeric formatting */
.price { font-variant-numeric: tabular-nums; } /* fixed-width digits */
line-height – Readability Spacing
line-height controls the vertical space between lines of text. It is one of the most important properties for readability.
/* Unitless number — recommended (multiplies the current font-size) */
p { line-height: 1.6; } /* 1.6 × 16px = 25.6px */
h1 { line-height: 1.2; } /* headings need tighter spacing */
code { line-height: 1.5; }
/* Fixed pixel — not recommended (doesn't scale with font-size) */
p { line-height: 24px; }
/* Em or rem */
p { line-height: 1.6em; }
/* Normal — browser default (~1.2) */
p { line-height: normal; }
/* Rule of thumb for body text */
body { line-height: 1.6; } /* minimum for comfortable reading */
Text Alignment and Spacing
/* Horizontal alignment */
text-align: left; /* default in LTR languages */
text-align: center;
text-align: right;
text-align: justify; /* stretches lines to fill width (use with care) */
text-align: start; /* respects text direction (LTR = left, RTL = right) */
/* Letter spacing */
letter-spacing: 0.05em; /* slight open tracking — good for caps */
letter-spacing: 2px; /* fixed — less flexible */
letter-spacing: normal; /* default */
/* Word spacing */
word-spacing: 4px;
word-spacing: 0.2em;
/* Text indentation */
text-indent: 2rem; /* indent first line, like a book paragraph */
/* Vertical alignment (for inline elements) */
vertical-align: baseline;
vertical-align: middle;
vertical-align: top;
vertical-align: sub; /* subscript */
vertical-align: super; /* superscript */
text-decoration – Underlines, Strikethrough
/* Remove underline from links */
a { text-decoration: none; }
/* Add it back on hover */
a:hover { text-decoration: underline; }
/* Strikethrough */
.sale-price del { text-decoration: line-through; }
/* Overline */
.overlined { text-decoration: overline; }
/* Shorthand: line style color thickness */
a { text-decoration: underline dotted #1572B6 2px; }
/* Underline offset (spacing from baseline) */
a { text-underline-offset: 4px; }
/* Remove underline from subscript/superscript */
sub, sup { text-decoration: none; }
text-transform and White Space
/* Transform case in CSS (without changing HTML) */
.nav-link { text-transform: uppercase; }
.card-title { text-transform: capitalize; } /* Title Case */
.byline { text-transform: lowercase; }
button { text-transform: none; } /* override inherited */
/* White space handling */
.code-snippet { white-space: pre; } /* preserve whitespace and line breaks */
.no-wrap { white-space: nowrap; } /* prevent line breaks */
p { white-space: normal; } /* default — wrap at word boundaries */
/* Overflow for text — truncate long text with ellipsis */
.card-title {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis; /* shows "..." when truncated */
}
/* Multi-line text clamp (limit to N lines) */
.card-desc {
display: -webkit-box;
-webkit-line-clamp: 3; /* show max 3 lines */
-webkit-box-orient: vertical;
overflow: hidden;
}
The font Shorthand
Combine multiple font properties in one declaration:
/* font: style variant weight size/line-height family */
h1 { font: 700 2.5rem/1.2 'Playfair Display', serif; }
p { font: normal 400 1rem/1.6 'Inter', sans-serif; }
/* font: size family — minimum valid shorthand */
small { font: 0.875rem sans-serif; }
📋 Summary
- font-family — provide a stack of fonts + generic fallback. Load custom fonts via Google Fonts or
@font-face. - font-size — use
remfor accessibility.clamp()for fluid headings. - font-weight — 100–900 numeric or
bold/normalkeywords. - line-height — unitless number (1.5–1.7 for body text, 1.1–1.3 for headings).
- text-align — left, center, right, justify.
- letter-spacing — use
emunits; positive value opens tracking (good for caps). - text-decoration — control underlines, strikethrough, color, and offset.
- text-transform — uppercase, capitalize, lowercase without touching HTML.
- text-overflow: ellipsis — truncate overflowing text with "…"
Frequently Asked Questions
The standard is 16px (1rem) for desktop body text — this is the browser default and is well-researched for readability. On mobile, 15–16px is ideal. Anything below 14px is problematic for readability and accessibility. For long-form articles, 17–18px can actually improve reading comfort on large screens. Never go below 14px for body text.
For body text: 1.5–1.7 (unitless). For headings: 1.1–1.3. For compact UI labels: 1.2–1.4. The unitless form is preferred because it scales proportionally when the font-size changes. The W3C accessibility guidelines recommend a line-height of at least 1.5 for body text.
For performance: system fonts are faster — no extra network request. The system font stack (-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif) looks native and loads instantly. For design: Google Fonts give you better aesthetic control and brand consistency. If you use Google Fonts, always add display=swap to the URL and <link rel="preconnect"> tags to minimize load impact.
Use @font-face to load a font file you host yourself:
@font-face {
font-family: 'MyFont';
src: url('/fonts/myfont.woff2') format('woff2'),
url('/fonts/myfont.woff') format('woff');
font-weight: 400;
font-style: normal;
font-display: swap; /* show fallback while loading */
}
body { font-family: 'MyFont', sans-serif; }
Always provide woff2 (best compression, all modern browsers) and woff as fallback.