Beginner9 min read

CSS Typography: Fonts, Text Styling, and Readability

9 min read
344 words
14 sections11 code blocks

Why Typography Matters

Typography is one of the most impactful parts of web design. Over 90% of the web is text, so how you style that text dramatically affects readability, user experience, and the overall feel of your site.

Font Family

The `font-family` property sets the typeface for text. You should always provide a fallback stack in case the preferred font is not available.

CSS
body {
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

h1, h2, h3 {
  font-family: 'Georgia', 'Times New Roman', Times, serif;
}

code, pre {
  font-family: 'Fira Code', 'Consolas', 'Courier New', monospace;
}

Font Family Categories

There are five generic font families that act as ultimate fallbacks:

  • serif: Fonts with small decorative lines (Georgia, Times New Roman)
  • sans-serif: Clean fonts without decorative lines (Arial, Helvetica, Verdana)
  • monospace: Every character has the same width (Courier New, Consolas)
  • cursive: Handwriting-style fonts (Brush Script, Comic Sans)
  • fantasy: Decorative or display fonts (Impact, Papyrus)

Always end your font stack with a generic family name.

Font Size

The `font-size` property controls the size of text. Use `rem` for accessible, scalable typography.

CSS
html {
  font-size: 16px;  /* Base size - 1rem = 16px */
}

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

h1 { font-size: 2.5rem; }   /* 40px */
h2 { font-size: 2rem; }     /* 32px */
h3 { font-size: 1.75rem; }  /* 28px */
h4 { font-size: 1.5rem; }   /* 24px */
h5 { font-size: 1.25rem; }  /* 20px */
h6 { font-size: 1rem; }     /* 16px */

.small-text {
  font-size: 0.875rem;  /* 14px */
}

.caption {
  font-size: 0.75rem;   /* 12px */
}

Font Weight

The `font-weight` property controls how thick or thin characters appear.

CSS
.thin { font-weight: 100; }
.light { font-weight: 300; }
.normal { font-weight: 400; }      /* Same as font-weight: normal */
.medium { font-weight: 500; }
.semi-bold { font-weight: 600; }
.bold { font-weight: 700; }        /* Same as font-weight: bold */
.extra-bold { font-weight: 800; }
.black { font-weight: 900; }

/* Practical usage */
body { font-weight: 400; }
h1, h2, h3 { font-weight: 700; }
.subtitle { font-weight: 300; }
strong { font-weight: 600; }

Font Style

The `font-style` property is used primarily for italics.

CSS
.normal { font-style: normal; }
.italic { font-style: italic; }
.oblique { font-style: oblique; }

em { font-style: italic; }

/* Remove default italic from <em> or <address> */
address {
  font-style: normal;
}

Line Height

The `line-height` property controls the space between lines of text. It is one of the most important properties for readability.

CSS
body {
  line-height: 1.6;   /* 1.6 times the font size - good for body text */
}

h1 {
  line-height: 1.2;   /* Tighter for headings */
}

h2 {
  line-height: 1.3;
}

p {
  line-height: 1.8;   /* More generous for long paragraphs */
}

.compact {
  line-height: 1.4;
}

Best practice: Use unitless values for line-height. A value like `1.6` means 1.6 times the element's font size, and it scales properly when font size changes.

Text Alignment

The `text-align` property controls horizontal alignment of text.

CSS
.left { text-align: left; }         /* Default for LTR languages */
.center { text-align: center; }
.right { text-align: right; }
.justify { text-align: justify; }   /* Stretches lines to equal width */

/* Practical usage */
.page-title {
  text-align: center;
}

.article-body {
  text-align: left;
}

.price {
  text-align: right;
}

Text Decoration

The `text-decoration` property adds visual decorations to text.

CSS
.underline { text-decoration: underline; }
.overline { text-decoration: overline; }
.line-through { text-decoration: line-through; }
.none { text-decoration: none; }

/* Remove underline from links */
a {
  text-decoration: none;
  color: #3498db;
}

a:hover {
  text-decoration: underline;
}

/* Styled underline */
.fancy-underline {
  text-decoration: underline;
  text-decoration-color: #3498db;
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}

/* Strikethrough for sale prices */
.original-price {
  text-decoration: line-through;
  color: #999;
}

Text Transform

The `text-transform` property changes the capitalization of text.

CSS
.uppercase { text-transform: uppercase; }
.lowercase { text-transform: lowercase; }
.capitalize { text-transform: capitalize; }  /* First letter of each word */
.normal-case { text-transform: none; }

/* Common usage */
.button {
  text-transform: uppercase;
  letter-spacing: 1px;
  font-size: 0.875rem;
}

.section-label {
  text-transform: uppercase;
  font-size: 0.75rem;
  font-weight: 600;
  color: #888;
  letter-spacing: 2px;
}

Letter Spacing and Word Spacing

CSS
/* Letter spacing */
.tight { letter-spacing: -0.5px; }
.normal { letter-spacing: 0; }
.wide { letter-spacing: 1px; }
.very-wide { letter-spacing: 3px; }

/* Word spacing */
.wide-words { word-spacing: 4px; }

/* Uppercase text looks better with wider letter-spacing */
.heading-label {
  text-transform: uppercase;
  letter-spacing: 2px;
  font-size: 0.8rem;
}

Text Overflow and Wrapping

Control what happens when text is too long for its container.

CSS
/* Single line truncation with ellipsis */
.truncate {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Multi-line truncation (modern browsers) */
.truncate-lines {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Break long words */
.break-words {
  word-break: break-word;
  overflow-wrap: break-word;
}

A Complete Typography System

CSS
/* Base typography */
html {
  font-size: 16px;
}

body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.6;
  color: #333;
}

/* Headings */
h1, h2, h3, h4, h5, h6 {
  font-weight: 700;
  line-height: 1.2;
  margin-top: 2rem;
  margin-bottom: 1rem;
  color: #1a1a2e;
}

h1 { font-size: 2.5rem; }
h2 { font-size: 2rem; }
h3 { font-size: 1.5rem; }
h4 { font-size: 1.25rem; }

/* Paragraphs */
p {
  margin-bottom: 1.5rem;
  max-width: 70ch;  /* Optimal reading width */
}

/* Links */
a {
  color: #3498db;
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

/* Lists */
ul, ol {
  margin-bottom: 1.5rem;
  padding-left: 1.5rem;
}

li {
  margin-bottom: 0.5rem;
}

/* Blockquotes */
blockquote {
  border-left: 4px solid #3498db;
  padding-left: 1.5rem;
  margin: 2rem 0;
  font-style: italic;
  color: #555;
}

/* Code */
code {
  font-family: 'Fira Code', monospace;
  background-color: #f4f4f4;
  padding: 2px 6px;
  border-radius: 3px;
  font-size: 0.875rem;
}

Summary

Good typography makes your website readable, accessible, and professional. Set a clear font stack with fallbacks, use `rem` for scalable font sizes, maintain generous line-height for body text, and limit paragraph width to around 70 characters for optimal readability. A well-structured typography system creates visual hierarchy and guides readers through your content.

In the next article, you will learn how to use custom web fonts with @font-face.