Mobile-First Typography — Complete Guide
In this tutorial, you will learn about Mobile. We cover key concepts, practical examples, and best practices to help you master this topic.
Mobile-first typography uses fluid type scales, adequate line heights, 16px minimum for inputs, and responsive spacing for comfortable reading on small screens.
What You'll Learn
- Fluid type scales with clamp()
- Line height and measure for mobile
- Font sizing best practices
- Responsive spacing for text
- Input font size rules
- System font stacks for performance
- Accessibility of type on mobile
Why It Matters
- Text is the primary content on most sites
- Poor typography makes reading difficult
- Mobile screens demand larger base sizes
- Wrong font sizes cause iOS zoom
Real-World Use
- A blog uses fluid type for headings that scale with viewport
- An e-commerce site sets 16px minimum on all inputs
- A news site uses a modular scale for consistent rhythm
- A SaaS app uses system fonts for fast loading
flowchart LR A[Mobile Typography] --> B[Fluid Scale] A --> C[Line Height] A --> D[Font Size] A --> E[Measure] B --> F[clamp(min, preferred, max)] C --> G[1.5-1.6 for body] D --> H[16px minimum for inputs] E --> I[45-75 characters]
Type Fundamentals
Code Example: Fluid Type Scale
/* Fluid type scale using clamp() */
/* Base: 16px on mobile, scales up to 18px on desktop */
body {
font-size: clamp(1rem, 0.5rem + 1vw, 1.125rem);
line-height: 1.6;
}
/* Modular scale with ratio 1.25 (major third) */
:root {
--text-xs: clamp(0.75rem, 0.7rem + 0.25vw, 0.875rem);
--text-sm: clamp(0.875rem, 0.8rem + 0.25vw, 1rem);
--text-base: clamp(1rem, 0.9rem + 0.25vw, 1.125rem);
--text-lg: clamp(1.125rem, 1rem + 0.5vw, 1.375rem);
--text-xl: clamp(1.25rem, 1rem + 0.75vw, 1.75rem);
--text-2xl: clamp(1.5rem, 1rem + 1.5vw, 2.25rem);
--text-3xl: clamp(2rem, 1.5rem + 2vw, 3rem);
--text-4xl: clamp(2.5rem, 2rem + 2.5vw, 4rem);
}
body {
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
font-size: var(--text-base);
line-height: 1.6;
color: #1a1a2e;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
h1 { font-size: var(--text-4xl); line-height: 1.1; }
h2 { font-size: var(--text-3xl); line-height: 1.2; }
h3 { font-size: var(--text-2xl); line-height: 1.3; }
h4 { font-size: var(--text-xl); line-height: 1.4; }
h5 { font-size: var(--text-lg); line-height: 1.5; }
h6 { font-size: var(--text-base); line-height: 1.6; }
small, .text-small { font-size: var(--text-sm); }
.text-xs { font-size: var(--text-xs); }
Expected output: On a 375px phone, body text is 16px and h1 is 40px. On a 1440px desktop, body text is 18px and h1 is 64px. The scale transitions smoothly without breakpoints.
Code Example: Line Height and Measure
/* Line height adjustments for mobile */
body {
font-size: 16px;
line-height: 1.6; /* Generous for mobile readability */
}
/* Tighter for headings */
h1, h2, h3 {
line-height: 1.2;
}
/* Optimal measure (line length) */
.content {
max-width: 65ch; /* 65 characters per line maximum */
margin: 0 auto;
}
/* On very small screens, let measure be full width */
@media (max-width: 480px) {
.content {
max-width: 100%;
padding: 0 1rem;
}
}
/* Paragraph spacing */
p {
margin: 0 0 1.5em; /* Relative to font size */
}
/* Last paragraph should not have margin */
p:last-child {
margin-bottom: 0;
}
/* List spacing for mobile */
ul, ol {
padding-left: 1.5rem; /* Indent for readability */
margin: 0 0 1.5rem;
}
ul li, ol li {
margin-bottom: 0.5em; /* Space between list items */
}
/* Blockquotes */
blockquote {
margin: 1.5rem 0;
padding: 1rem 1.5rem;
border-left: 4px solid #0066CC;
font-style: italic;
line-height: 1.7;
}
Expected output: Body text has comfortable line spacing for mobile reading. Line length is capped at 65 characters on wider screens to prevent eye strain from long lines. Paragraph spacing is relative to font size.
Code Example: Input Font Size Rule
/* Critical: prevent iOS zoom on focus */
/* Any input with font-size below 16px triggers iOS auto-zoom */
input,
textarea,
select,
[contenteditable] {
font-size: 16px; /* Minimum 16px to prevent iOS zoom */
line-height: 1.5;
}
/* Mobile-friendly form typography */
.form-group {
margin-bottom: 1rem;
}
.form-group label {
display: block;
font-size: 0.875rem;
font-weight: 500;
margin-bottom: 0.25rem;
color: #555;
}
.form-group input,
.form-group textarea,
.form-group select {
width: 100%;
padding: 0.75rem;
font-size: 16px; /* iOS zoom prevention */
border: 1px solid #ccc;
border-radius: 4px;
-webkit-appearance: none; /* Remove iOS default styling */
appearance: none;
}
.form-group textarea {
line-height: 1.6;
min-height: 120px;
resize: vertical;
}
/* Search input */
input[type="search"] {
-webkit-appearance: none;
appearance: none;
border-radius: 8px;
}
/* Buttons and CTAs */
button,
.button {
font-size: 1rem;
font-weight: 500;
padding: 0.75rem 1.5rem;
min-height: 44px;
line-height: 1;
}
/* Error state */
.form-group.has-error input {
border-color: #dc3545;
}
.form-group .error-message {
color: #dc3545;
font-size: 0.875rem;
margin-top: 0.25rem;
}
Expected output: All inputs have 16px font size, preventing iOS Safari from zooming into the input. Labels are positioned above inputs for easy reading on mobile.
Code Example: Responsive Spacing
/* Fluid spacing for text elements */
.content {
/* Vertical rhythm */
> * + * {
margin-top: 1.5em;
}
}
/* Section spacing */
.section {
padding: clamp(2rem, 5vw, 5rem) 1rem;
}
.hero {
padding: clamp(3rem, 8vw, 8rem) 1rem;
text-align: center;
}
/* Button spacing */
.button-group {
display: flex;
gap: 0.75rem;
flex-wrap: wrap;
}
.button-group .button {
flex: 1 1 auto;
min-width: 120px;
}
/* Full-width button on mobile */
@media (max-width: 480px) {
.button-group .button {
flex: 1 1 100%;
}
}
/* Card spacing */
.card {
padding: clamp(1rem, 3vw, 2rem);
}
.card + .card {
margin-top: clamp(1rem, 2vw, 1.5rem);
}
Expected output: Spacing scales fluidly between mobile and desktop. Vertical rhythm maintains consistent spacing between elements. Buttons stack vertically on very small screens.
Common Mistakes
- Font size below 16px on inputs — iOS Safari zooms into inputs with font sizes below 16px. Always use 16px minimum.
- Line height too tight on mobile — Lower line heights (1.2-1.3) for body text make reading harder on small screens. Use 1.5-1.6.
- Fixed font sizes — Using px for all font sizes means text is the same size on a 375px phone and a 1440px monitor. Use clamp() or rem.
- No maximum line length — Body text that spans the full width of a 1440px screen (90+ characters) is hard to read. Cap at 65-75ch.
- Touch targets too small for text links — Inline links need adequate padding to meet 44px touch targets. Add padding or increase line height.
- System font not used — Custom fonts add loading time. Use system font stack as the primary with custom fonts as progressive enhancement.
- Not testing with real content — Lorem ipsum looks different than real text. Test typography with actual content length and language.
Practice Questions
- What is the minimum font size for mobile inputs to prevent iOS zoom? 16px (1rem).
- What is the optimal line length (measure) for body text? 45-75 characters per line, with 65-70ch as the ideal maximum.
- What CSS function enables fluid typography? clamp(min, preferred, max) for values that scale between bounds.
- Why is system font stack recommended for mobile? Custom fonts add HTTP requests and render blocking. System fonts are already installed and render instantly.
FAQ
Mini Project
Build a responsive typography system for a content site. Create: (1) a fluid type scale using clamp() with 7 sizes (xs through 4xl), (2) a system font stack, (3) line heights that adjust for reading comfort, (4) input font size at 16px minimum with proper styling, (5) fluid spacing using clamp() for sections and cards, (6) maximum line length at 65ch, (7) all form elements with 16px+ font size. Create a sample article page that uses the typography system. Test on a real phone at various zoom levels. Verify inputs do not trigger iOS zoom.
What's Next
Continue with Lesson 5: Mobile-First Images to optimize images for mobile.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro