XenT Typography System: Complete Font-Size and Line-Height Consolidation

XenT Typography System: Complete Font-Size and Line-Height Consolidation

The Problem: Typography Chaos Across Two Dimensions

During comprehensive audits of the XenT theme codebase, we uncovered significant inconsistencies in both font-size and line-height implementations that were undermining user experience and maintainability. Components serving similar functions had wildly different sizing, language support was fragmented, and hardcoded values were scattered across 40+ files.

This post documents our complete typography system transformation, covering both the font-size rationalization and the new language-aware line-height consolidation that brings order to XenT’s typography.

🚨 Critical Issues Identified

1. Breakpoint Fragmentation

Our responsive system was fragmented across different breakpoint values:

  • Some components used max-width: 767px for mobile
  • Others used max-width: 768px for the same purpose
  • Small mobile breakpoints varied between 479px and 480px
  • Component-specific breakpoints like 600px and 400px created maintenance nightmares

2. Unit Type Chaos

Components mixed em, rem, and px units without any coherent strategy:

/* Found in PostMeta.astro - completely inconsistent */
.meta-item {
  font-size: 0.85em;
}
.other-meta {
  font-size: 0.85rem;
}
.date {
  font-size: 0.8em;
}
.category {
  font-size: 0.8rem;
}

3. Arbitrary Font-Size Values

The codebase contained numerous arbitrary font-size values that didn’t follow any systematic scale:

  • 0.8125em, 0.95rem, 1.1em scattered throughout
  • Archive components using excessive 2.5rem and 3rem sizes
  • Button text varying from 0.8em to 1em across similar components

4. Inconsistent Component Sizing

Components serving similar UI functions had different font sizes:

  • Sidebar elements: TOC used 0.875em, Blogroll used 0.8125em, RelatedPosts used 0.85em
  • Metadata: Some used 0.85em, others 0.85rem, 0.8rem, or 0.875em
  • Buttons: Submit buttons, read-more buttons, and navigation buttons all had different sizing

5. Line-Height Chaos and Language Conflicts

Our line-height implementation was even more problematic with 40+ hardcoded values creating a maintenance nightmare:

Random Hardcoded Values Everywhere:

  • 1.0, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8 scattered across components
  • No semantic meaning - developers couldn’t know which value to use when
  • TOC used 1.8, PostList used 1.4, SearchInterface used 1.5 - completely arbitrary

Conflicting Systems:

/* Global variables */
--line-height-base: 1.7;

/* Component-level language overrides fighting with global */
.post-content[lang='zh'] {
  line-height: 1.8;
}
.post-content[lang='en'] {
  line-height: 1.6;
}

/* Random hardcoded values in components */
.toc-link {
  line-height: 1.8;
}
.post-meta {
  line-height: 1.4;
}

Language Integration Problems:

  • Component-level language overrides fighting with design system
  • No proper CSS cascade - language attributes not leveraged correctly
  • Mixed approaches: some used global variables, others hardcoded values

The Solution: Unified Typography System

πŸ“ Standardized Typography Scale

We’ve established a coherent font-size scale using rem units for predictable, non-compounding behavior:

/* XenT Typography Scale - rem for Predictable Sizing */

/* Very small mobile default (<480px) - Most compact scale */
--font-xs: 0.75rem; /* 12px - Fine print */
--font-sm: 0.8125rem; /* 13px - Metadata */
--font-ui: 0.875rem; /* 14px - UI controls */
--font-base: 1rem; /* 16px - Body text anchor */
--font-lg: 1.125rem; /* 18px - Emphasized content */
--font-xl: 1.0625rem; /* 17px - Small headings (h4) */
--font-2xl: 1.125rem; /* 18px - Medium headings (h3) */
--font-3xl: 1.25rem; /* 20px - Large headings, post titles (h2) */
--font-4xl: 1.375rem; /* 22px - Page titles (h1) */

/* Larger phones (β‰₯480px) */
--font-xl: 1.125rem; /* 18px */
--font-2xl: 1.25rem; /* 20px */
--font-3xl: 1.375rem; /* 22px */
--font-4xl: 1.5rem; /* 24px */

/* Tablet/Desktop (β‰₯768px) */
--font-xl: 1.25rem; /* 20px */
--font-2xl: 1.375rem; /* 22px */
--font-3xl: 1.5rem; /* 24px */
--font-4xl: 1.625rem; /* 26px */

/* Large desktop (β‰₯1200px) */
--font-sm: 0.875rem; /* 14px - Enhanced metadata readability */
--font-xl: 1.3125rem; /* 21px */
--font-2xl: 1.5rem; /* 24px */
--font-3xl: 1.6875rem; /* 27px */
--font-4xl: 1.875rem; /* 30px */

/* iOS Input Prevention */
--font-input-mobile: 16px;

Why rem instead of em:

  • rem always references root html font-size (16px), never compounds when nested
  • Example: .parent { font-size: var(--font-sm) } .child { font-size: var(--font-sm) }
    • With rem: Both = 13px βœ“
    • With em: Parent = 13px, Child = 10.5px (13px Γ— 0.8125) ❌
  • Industry standard: Tailwind, Bootstrap, Material UI all use rem for font-size

πŸ“ Language-Aware Line-Height System

We’ve created a semantic line-height system that integrates seamlessly with language support:

/* Line Height System - Language-aware design tokens */
--line-height-base: 1.7; /* Main content reading */
--line-height-compact: 1.4; /* Lists, navigation, UI elements */
--line-height-tight: 1.2; /* Metadata, captions, fine print */
--line-height-loose: 1.8; /* TOC, generous spacing */
--line-height-minimal: 1; /* Icons, buttons, badges */
--line-height-code: 1.6; /* Code blocks and inline code */
--line-height-headings: 1.6; /* Headings (language-aware) */

/* Language-specific overrides at root level */
:root[lang='zh'],
[lang='zh'] {
  --line-height-base: 1.8;
  --line-height-compact: 1.5;
  --line-height-headings: 1.6;
}

:root[lang='en'],
[lang='en'] {
  --line-height-base: 1.6;
  --line-height-compact: 1.4;
  --line-height-headings: 1.5;
}

Key Benefits:

  • Semantic naming - developers know which variable to use for each context
  • Language integration - proper CSS cascade from <html lang> attributes
  • No conflicts - single source of truth, no component-level overrides
  • Maintainability - 7 variables replace 40+ hardcoded values

🎯 Unified Breakpoint System

All typography now uses a centralized 4-breakpoint system in global.css:

/* Centralized responsive typography - 4 breakpoints */

/* Default (<480px) - Very small mobile */
:root {
  --font-3xl: 1.25rem; /* 20px post titles */
}

/* Larger phones (β‰₯480px) */
@media (min-width: 480px) {
  :root {
    --font-3xl: 1.375rem; /* 22px post titles */
  }
}

/* Tablet/Desktop (β‰₯768px) */
@media (min-width: 768px) {
  :root {
    --font-3xl: 1.5rem; /* 24px post titles */
  }
}

/* Large desktop (β‰₯1200px) */
@media (min-width: 1200px) {
  :root {
    --font-sm: 0.875rem; /* 14px metadata */
    --font-3xl: 1.6875rem; /* 27px post titles */
  }
}

Critical principle: Components should NEVER override font-size in their own media queries. All responsive typography scaling happens in global.css through CSS custom property updates.

Component Category Standards

Components reference semantic font-size variables. Responsive scaling happens automatically through global.css:

1. Content Components (PostBody, Comments, Main Text)

.content-text {
  font-size: var(--font-base); /* 16px constant across all breakpoints */
  line-height: var(--line-height-base); /* Language-aware: 1.7 default, 2.0 CJK */
}
/* NO component-level responsive overrides! */
/* Body text stays at 16px for readability anchor */

2. UI Components (Navigation, Buttons, Sidebar)

.ui-element {
  font-size: var(--font-ui); /* 14px constant across all breakpoints */
  line-height: var(--line-height-compact); /* 1.6 default, 1.8 CJK */
}
/* NO component-level responsive overrides! */
/* UI elements maintain consistent size for predictability */

3. Metadata Components (Post meta, dates, secondary info)

.metadata {
  font-size: var(--font-sm); /* 13px β†’ 14px at 1200px+ (global.css handles this) */
  line-height: var(--line-height-tight); /* 1.2 for compact display */
}
/* NO component-level responsive overrides! */
/* Metadata scales slightly at 1200px+ via global.css */

4. Headings (Responsive via Global Variables)

.post-title {
  font-size: var(--font-3xl); /* Scales: 20px β†’ 22px β†’ 24px β†’ 27px */
  font-weight: 600;
  line-height: var(--line-height-headings); /* 1.7 default, 1.8 CJK */
}

.section-title {
  font-size: var(--font-2xl); /* Scales: 18px β†’ 20px β†’ 22px β†’ 24px */
  font-weight: 600;
}
/* NO component-level responsive overrides! */
/* Headings scale automatically via global.css breakpoints */

Clear Unit Usage Rules

Critical change: All font-size custom properties now use rem (not em) to prevent compounding.

Use rem for:

  • βœ… All font-size custom properties (--font-xs through --font-4xl)
  • βœ… Typography that must be predictable regardless of nesting depth
  • βœ… Design system tokens (our centralized typography scale)
  • βœ… Prevents compounding: rem always references root (16px), never parent

Why rem for font-size:

/* With rem - PREDICTABLE βœ“ */
.parent {
  font-size: var(--font-sm);
} /* 0.8125rem = 13px */
.child {
  font-size: var(--font-sm);
} /* 0.8125rem = 13px */

/* With em - COMPOUNDS ❌ */
.parent {
  font-size: var(--font-sm);
} /* 0.8125em = 13px */
.child {
  font-size: var(--font-sm);
} /* 0.8125em Γ— 13px = 10.5px WRONG! */

Use em for:

  • βœ… Padding/margin relative to element’s font-size (e.g., padding: 0.5em on buttons)
  • βœ… Line-height (unitless is usually better, but em works)
  • βœ… Intentional relative sizing within a component

Use px for:

  • βœ… iOS input prevention only (font-size: 16px on inputs)
  • βœ… Fine borders (border: 1px solid)
  • ❌ Never for responsive font-sizing (breaks user zoom, not scalable)

Priority Cleanup Roadmap

πŸ”΄ Critical Fixes (Immediate)

  1. Archive Components Oversizing

    /* WRONG - Current excessive sizing */
    .archive-title {
      font-size: 3rem;
    }
    
    /* CORRECT - Hierarchy-respecting */
    .archive-title {
      font-size: 1.625em;
    } /* Match h1 */
  2. Breakpoint Standardization

    /* WRONG - Inconsistent breakpoint */
    @media (max-width: 768px) {
    }
    
    /* CORRECT - Standard breakpoint */
    @media (max-width: 767px) {
    }

🟑 Important Fixes (Next Phase)

  1. PostMeta Unit Mixing - Eliminate the chaotic mixing of em/rem units
  2. Sidebar Component Unification - Standardize all sidebar elements to consistent sizing
  3. Button Consistency - Unify all button text sizing across the theme

Implementation Benefits

This systematic approach provides several key benefits:

User Experience

  • Consistent visual hierarchy across all pages and components
  • Predictable responsive behavior with systematic scaling
  • Better readability with proper content scaling on large screens
  • Touch-friendly interfaces with appropriate mobile sizing

Developer Experience

  • Reduced cognitive load - developers know which sizes to use
  • Easier maintenance - consistent patterns across components
  • Better debugging - systematic approach makes issues easier to spot
  • Future-proof scaling - new components follow established patterns

Performance

  • Reduced CSS complexity through systematic sizing
  • Better caching with fewer arbitrary values
  • Cleaner compiled output with consistent patterns

Testing & Validation

Every component should now pass this comprehensive checklist:

Font-Size Requirements

  1. βœ… Uses only approved font-size values from the standardized scale
  2. βœ… Uses consistent breakpoints (1200px, 767px, 479px)
  3. βœ… Follows appropriate scaling pattern (Content vs UI vs Metadata)
  4. βœ… Uses proper unit type (em for components, rem for architecture, px for iOS)

Line-Height Requirements

  1. βœ… Uses semantic line-height variables - no hardcoded values
  2. βœ… Appropriate line-height category (base/compact/tight/loose/minimal/code/headings)
  3. βœ… Language-aware - respects CSS cascade from lang attributes
  4. βœ… No component-level language overrides - uses root-level system

Overall System

  1. βœ… Maintains visual hierarchy with other components
  2. βœ… Consistent with language support - works across zh/en/ja contexts

Implementation Strategy

This system provides direct, clean typography properties:

Complete System Usage

/* Centralized typography system - components just reference variables */

.sidebar-widget {
  font-size: var(--font-ui); /* 14px constant */
  line-height: var(--line-height-compact); /* 1.6 default, 1.8 CJK */
}
/* NO media queries! UI elements stay consistent */

.post-meta {
  font-size: var(--font-sm); /* 13px β†’ 14px at 1200px+ (automatic) */
  line-height: var(--line-height-compact); /* 1.6 default, 1.8 CJK */
}
/* NO media queries! Scaling handled by global.css */

.post-content {
  font-size: var(--font-base); /* 16px constant - readability anchor */
  line-height: var(--line-height-base); /* 1.7 default, 2.0 CJK */
}
/* NO media queries! Body text stays at 16px for readability */

.post-title {
  font-size: var(--font-3xl); /* 20px β†’ 22px β†’ 24px β†’ 27px (automatic) */
  font-weight: 600;
  line-height: var(--line-height-headings); /* 1.7 default, 1.8 CJK */
}
/* NO media queries! Heading scales via global.css */

.toc-link {
  font-size: var(--font-ui); /* 14px constant */
  line-height: var(--line-height-loose); /* 1.9 - generous TOC spacing */
}

.code-block {
  font-family: var(--font-family-monospace);
  line-height: var(--line-height-code); /* 1.7 - optimal for code */
}

.button-text {
  font-size: var(--font-ui); /* 14px constant */
  line-height: var(--line-height-minimal); /* 1.0 - tight buttons */
  padding: 0.5em 1em; /* em for relative padding */
}

Benefits of This Complete System

  1. Unified approach - font-size and line-height work together seamlessly
  2. Language-aware - automatic adaptation for Chinese, English, Japanese
  3. Self-documenting - semantic names guide developers to correct choices
  4. Maintainable - single source of truth for all typography decisions
  5. CSS cascade leverage - proper inheritance from lang attributes

Benefits Achieved

This comprehensive typography system delivers substantial improvements:

User Experience

  • Consistent visual hierarchy across all pages and components
  • Language-optimized readability - Chinese gets higher line-heights, English gets efficient density
  • Predictable responsive behavior with systematic scaling
  • Better accessibility - proper semantic HTML with lang attributes
  • Professional typography - no more random sizing decisions

Developer Experience

  • Clear decision tree - semantic variable names eliminate guesswork
  • Reduced cognitive load - know exactly which variable to use when
  • No conflicts - language support works automatically via CSS cascade
  • Easy maintenance - system-wide adjustments in a few variables
  • Better debugging - semantic names make issues obvious
  • Future-proof - new components inherit language support automatically

Architectural Benefits

  • Single source of truth - all typography decisions centralized
  • Language infrastructure - ready for additional languages
  • Design system ready - proper tokens for theme variations
  • Performance optimized - fewer CSS variables, better browser caching
  • Maintainable at scale - replaces 40+ hardcoded values with 7 semantic variables

This post documents the complete typography system transformation for XenT theme - covering both font-size standardization and line-height consolidation with language-aware design tokens. The result is a unified, maintainable typography system that automatically adapts to different languages while providing semantic clarity for developers.