👁️ Font Readability Testing
Readability is not just about choosing a nice font; it's about how that font behaves under different conditions. Is it legible on a cheap Android phone in bright sunlight? Is the contrast high enough for aging eyes? This guide outlines the testing protocol for the Mushroom Hub.
1. The Golden Rules of Typography for Educational Content
Psilobase covers complex scientific and harm-reduction topics. The typography must work hard to make dense information accessible — not just aesthetically pleasing but cognitively manageable. Users may be reading during stressful moments: researching drug interactions before a session, looking up safety information, or processing an intense experience afterward. Poor readability in those moments is a real safety concern.
✅ Good Readability Example
This paragraph follows the 65-character line-length rule. It is set in 18px with a line height of 1.7. The colour is a warm dark grey (#333) on white — not pure black, which reads as harsh under artificial light. The paragraphs are separated by 1.5× the line height so the eye can find the start of each new paragraph easily.
❌ Bad Readability Example
This text is too small (13px), the line height is 1.2 (cramped), and the line spans the full 1400px container width. The colour is mid-grey on dark grey — insufficient contrast. A user with moderate vision impairment cannot read this. Even a user with perfect vision will fatigue quickly on lines this wide and text this small.
2. Core Readability Metrics
📏 Line Length (Typographic Measure)
The ideal line length for body text is 45–75 characters per line (including spaces). This range is based on research into reading speed and comprehension — lines shorter than 45 characters feel choppy; longer than 75 causes the eye to struggle returning to the start of the next line, especially in long-form reading.
- Target: 55–65 characters for optimal reading comfort on desktop screens.
- CSS: Use
max-width: 65chon article containers. Thechunit is relative to the width of the "0" glyph in the current font, making it a typographically accurate measure. - Mobile: Enforce a minimum
padding: 0 16pxso text never reaches the screen edge. On 320px screens, even 16px padding each side leaves a 288px reading area — about 40–45 characters at 16px, which is acceptable. - Code blocks: Allow wider lines (up to 100 characters) in code blocks, which have a different reading pattern. Wrap in
overflow-x: auto.
📐 Line Height (Leading)
Line height controls the vertical space between lines and has a dramatic effect on reading comfort. Too tight and lines feel claustrophobic; too loose and the eye loses its tracking position.
- Body text:
line-height: 1.6to1.8. For long-form educational content (500+ word articles), 1.7 is ideal. - Headings: Tighter —
line-height: 1.1to1.3. Multi-line headings at 1.8 look like separated labels rather than a single heading. - Lists:
line-height: 1.6withmargin-bottom: 0.5embetween list items for complex technical lists. - Captions and small text: Paradoxically, small text benefits from more leading, not less — use
line-height: 1.8for text under 14px.
🔍 Font Size Scale
- Body text: 16px absolute minimum (1rem). Prefer 17–18px for long-form articles. At 18px, users can read comfortably without zooming on most screens.
- H1: 2.25–2.75rem (36–44px on desktop). Scale down to 1.75–2rem on mobile.
- H2: 1.75–2rem (28–32px). Main section headings within articles.
- H3: 1.25–1.5rem (20–24px). Sub-section headings.
- Small / captions: No smaller than 13px (0.8125rem). Below 12px is inaccessible for most users.
- Form inputs: Always 16px minimum on iOS. Below 16px triggers automatic zoom on Safari.
3. Font Selection for Psilobase
The font stack must balance personality, readability, and performance. Psilobase uses a nature-inspired but scientific aesthetic — the typefaces should feel approachable and credible, not clinical or psychedelic.
Recommended Font Pairings
- Option A (System Stack):
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif. Zero network cost. Renders familiarly on each OS. Best performance score. - Option B (Google Fonts): Inter for body + Merriweather for headings. Inter is designed for screen legibility; Merriweather has a humanist warmth that reduces clinical feeling on sensitive topics.
- Option C (Google Fonts): Source Sans 3 for body + Lora for headings. More editorial feel, suitable for long-form articles in the Research and Integration sections.
Weights to Load
Every additional font weight adds a network request and bytes to the critical path. Load only the weights you use:
- Regular (400): Body text — always needed.
- Medium (500): Navigation items, button labels — often needed.
- Bold (700): Headings, strong emphasis — always needed.
- Light (300): Avoid unless the design specifically requires it. Light weights render poorly on low-DPI screens and Windows ClearType.
- Italic: Load only if you use it for species names, citations, or pull quotes — otherwise skip it.
4. Device and Platform Testing Checklist
- iOS (iPhone/iPad, Safari): Check rendering of San Francisco system font if using the system stack. Verify that 16px+ on inputs prevents auto-zoom. Check
-webkit-font-smoothing: antialiasedeffect on body copy. - Android (Chrome, Pixel/Samsung): Roboto renders differently from Inter at the same pixel size. Check letter-spacing and word-spacing. Samsung devices may apply font scaling at OS level — test with display size set to Larger.
- Windows (Chrome/Edge, ClearType): ClearType sub-pixel rendering makes light font weights appear thinner than on macOS Retina. Avoid weights below 400 on Windows.
- Windows (Firefox, GDI rendering): Firefox on Windows uses GDI text rendering by default, which can make some Google Fonts look slightly heavier than in Chrome.
- Low-resolution monitors (96 DPI): Older 1080p monitors at 100% scaling still exist. Test that your font is not blurry or pixelated at this resolution — some variable fonts render poorly below 1.5× DPR.
- Dark Mode: Do not use pure white (#FFFFFF) text on pure black (#000000). The contrast is too high and causes halation. Use off-white (#E2E8F0 or #F0F0F0) on dark background (#0F0F0F or #1A1A1A).
- High Contrast Mode (Windows): All text must remain visible. Avoid setting text colour via background-clip or -webkit-text-fill-color for decorative headings, as these break in High Contrast mode.
- Browser font scaling: Users may set their browser's base font to 20px or 24px for accessibility. Always use relative units (rem, em) for font sizes so your scale is proportional to the user's preference.
5. Colour and Contrast
Readability is not just about font shape and size — colour contrast is equally critical. WCAG 2.1 AA requires:
- Normal text (under 18px / 14px bold): Minimum 4.5:1 contrast ratio against background.
- Large text (18px+ / 14px+ bold): Minimum 3:1 contrast ratio.
- UI components and graphical elements: Minimum 3:1 against adjacent colours.
For Psilobase's nature-inspired green palette (#2c5f2d), always verify the contrast ratio when using green for text. Dark greens typically pass on white; mid-range greens often fail.
Contrast Testing Tools
- WebAIM Contrast Checker: webaim.org/resources/contrastchecker/
- Chrome DevTools: Right-click any text element → Inspect → the Computed panel shows the contrast ratio.
- Colour Contrast Analyser (desktop app): By The Paciello Group — eyedropper tool for testing any colour on screen.
6. Accessibility: Beyond Contrast
Use the WCAG 2.1 AA standard as a minimum. For a harm-reduction site serving potentially vulnerable users, targeting AAA where feasible is worthwhile.
- 4.5:1 contrast ratio for normal text (AA). 7:1 for AAA.
- Zoom to 200%: All text must reflow without horizontal scrolling and remain legible. Test in browser with Ctrl/Cmd + scroll wheel.
- User font size override: In Firefox, force a base font size of 24px via about:preferences and verify the layout does not break.
- Dyslexia-friendly testing: Test with the OpenDyslexic browser extension to see how the layout changes when a user's custom font is applied.
- Focus indicators: All interactive text elements must have a visible
:focus-visiblering. Never useoutline: nonewithout providing an equally visible alternative.