Skip to main content

Custom Scales

Examples of creating and using custom typography scales.

Marketing Site Scale

Create custom scales for a marketing website:

tailwind.config.ts
import fluidTypography from 'fluid-typography'

export default {
plugins: [
fluidTypography({
customScales: {
'hero': {
size: [48, 96],
lineHeight: 1.0,
fontWeight: '900',
letterSpacing: '-0.03em'
},
'subhero': {
size: [32, 56],
lineHeight: 1.1,
fontWeight: '700',
letterSpacing: '-0.02em'
},
'feature-title': {
size: [24, 32],
lineHeight: 1.2,
fontWeight: '600'
}
},
minViewportWidth: 375,
maxViewportWidth: 1920
})
]
}
components/MarketingHero.tsx
export function MarketingHero() {
return (
<section className="py-20 px-4">
<div className="max-w-7xl mx-auto text-center">
<h1 className="text-hero mb-6 bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">
Transform Your Business
</h1>
<p className="text-subhero text-gray-700 mb-12 max-w-3xl mx-auto">
The all-in-one platform for modern teams
</p>
<div className="grid md:grid-cols-3 gap-8 mt-16">
<Feature
title="Lightning Fast"
description="Built for performance from the ground up"
/>
<Feature
title="Fully Secure"
description="Enterprise-grade security by default"
/>
<Feature
title="Always Available"
description="99.99% uptime guaranteed"
/>
</div>
</div>
</section>
)
}

function Feature({ title, description }) {
return (
<div className="text-center">
<h3 className="text-feature-title mb-3">{title}</h3>
<p className="text-body text-gray-600">{description}</p>
</div>
)
}

Blog Platform Scale

Typography for a content-focused blog:

tailwind.config.ts
import fluidTypography from 'fluid-typography'

export default {
plugins: [
fluidTypography({
customScales: {
'article-title': {
size: [32, 48],
lineHeight: 1.2,
fontWeight: '700',
letterSpacing: '-0.02em'
},
'article-lead': {
size: [18, 22],
lineHeight: 1.6,
fontWeight: '400'
},
'article-body': {
size: [16, 18],
lineHeight: 1.7,
fontWeight: '400'
},
'section-title': {
size: [24, 30],
lineHeight: 1.3,
fontWeight: '600'
}
},
minViewportWidth: 320,
maxViewportWidth: 800 // Narrow for reading
})
]
}
components/BlogArticle.tsx
export function BlogArticle() {
return (
<article className="max-w-3xl mx-auto px-4 py-12">
{/* Header */}
<header className="mb-12">
<span className="text-overline text-blue-600 block mb-3">
Design Systems
</span>
<h1 className="text-article-title mb-6">
Building Better Interfaces with Typography
</h1>
<p className="text-article-lead text-gray-700 mb-6">
Typography is more than choosing fonts. It's about creating
a visual hierarchy that guides readers through your content.
</p>
<div className="flex items-center gap-4 text-body-sm text-gray-600">
<img
src="/author.jpg"
alt="Author"
className="w-10 h-10 rounded-full"
/>
<div>
<div className="font-medium text-gray-900">Jane Smith</div>
<div>Dec 13, 2025 • 8 min read</div>
</div>
</div>
</header>

{/* Content */}
<div className="space-y-6">
<p className="text-article-body">
Great typography doesn't call attention to itself—it serves
the content and enhances the reading experience.
</p>

<h2 className="text-section-title mt-12 mb-4">
The Fundamentals
</h2>
<p className="text-article-body">
Start with a solid foundation: establish a clear hierarchy,
maintain consistent spacing, and choose appropriate sizes.
</p>

<h3 className="text-h3 mt-8 mb-4">Scale and Proportion</h3>
<p className="text-article-body">
A well-defined scale creates harmony and makes your content
easier to scan and understand.
</p>
</div>
</article>
)
}

Dashboard Scale

Scales for a data dashboard:

tailwind.config.ts
import fluidTypography from 'fluid-typography'

export default {
plugins: [
fluidTypography({
customScales: {
'metric': {
size: [40, 60],
lineHeight: 1.0,
fontWeight: '700'
},
'metric-label': {
size: [11, 13],
lineHeight: 1.4,
fontWeight: '600',
textTransform: 'uppercase',
letterSpacing: '0.05em'
},
'chart-title': {
size: [18, 22],
lineHeight: 1.3,
fontWeight: '600'
},
'dashboard-heading': {
size: [24, 32],
lineHeight: 1.2,
fontWeight: '700'
}
},
minViewportWidth: 1024, // Dashboard optimized for larger screens
maxViewportWidth: 1920
})
]
}
components/Dashboard.tsx
export function Dashboard() {
return (
<div className="p-6">
<h1 className="text-dashboard-heading mb-8">Analytics Overview</h1>

<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
<MetricCard
label="Total Revenue"
value="$128,450"
change="+12.5%"
trend="up"
/>
<MetricCard
label="Active Users"
value="12,345"
change="+8.2%"
trend="up"
/>
<MetricCard
label="Conversion Rate"
value="3.24%"
change="-2.1%"
trend="down"
/>
<MetricCard
label="Avg. Session"
value="4m 32s"
change="+5.4%"
trend="up"
/>
</div>

<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<ChartCard title="Revenue Trend" />
<ChartCard title="User Growth" />
</div>
</div>
)
}

function MetricCard({ label, value, change, trend }) {
return (
<div className="bg-white rounded-lg border p-6">
<div className="text-metric-label text-gray-600 mb-2">
{label}
</div>
<div className="text-metric text-gray-900 mb-2">
{value}
</div>
<div className={`text-body-sm font-medium ${
trend === 'up' ? 'text-green-600' : 'text-red-600'
}`}>
{change}
</div>
</div>
)
}

function ChartCard({ title }) {
return (
<div className="bg-white rounded-lg border p-6">
<h3 className="text-chart-title mb-4">{title}</h3>
<div className="h-64 bg-gray-50 rounded flex items-center justify-center">
Chart Placeholder
</div>
</div>
)
}

E-commerce Scale

Product page typography:

tailwind.config.ts
import fluidTypography from 'fluid-typography'

export default {
plugins: [
fluidTypography({
customScales: {
'product-name': {
size: [28, 40],
lineHeight: 1.2,
fontWeight: '700'
},
'product-price': {
size: [32, 48],
lineHeight: 1.0,
fontWeight: '800'
},
'badge': {
size: [11, 12],
lineHeight: 1.3,
fontWeight: '700',
textTransform: 'uppercase',
letterSpacing: '0.05em'
}
}
})
]
}
components/ProductCard.tsx
export function ProductCard({ product }) {
return (
<div className="border rounded-lg overflow-hidden hover:shadow-lg transition-shadow">
<div className="relative">
<img
src={product.image}
alt={product.name}
className="w-full aspect-square object-cover"
/>
{product.badge && (
<span className="absolute top-4 right-4 px-3 py-1 bg-red-600 text-white text-badge rounded">
{product.badge}
</span>
)}
</div>
<div className="p-6">
<h3 className="text-product-name mb-2">{product.name}</h3>
<p className="text-body-sm text-gray-600 mb-4">
{product.description}
</p>
<div className="flex items-center justify-between">
<span className="text-product-price text-blue-600">
${product.price}
</span>
<button className="px-4 py-2 text-body-sm font-medium bg-blue-600 text-white rounded">
Add to Cart
</button>
</div>
</div>
</div>
)
}

Portfolio Scale

Personal portfolio typography:

tailwind.config.ts
import fluidTypography from 'fluid-typography'

export default {
plugins: [
fluidTypography({
customScales: {
'portfolio-hero': {
size: [40, 72],
lineHeight: 1.1,
fontWeight: '800',
letterSpacing: '-0.02em'
},
'portfolio-subtitle': {
size: [20, 28],
lineHeight: 1.4,
fontWeight: '400'
},
'project-title': {
size: [24, 36],
lineHeight: 1.2,
fontWeight: '700'
}
},
minViewportWidth: 375,
maxViewportWidth: 1440
})
]
}
pages/portfolio.tsx
export default function Portfolio() {
return (
<div>
{/* Hero */}
<section className="min-h-screen flex items-center justify-center px-4">
<div className="max-w-4xl">
<h1 className="text-portfolio-hero mb-6">
Hi, I'm Alex.
<br />
Product Designer.
</h1>
<p className="text-portfolio-subtitle text-gray-600 max-w-2xl">
I craft beautiful, user-centered digital experiences that
solve real problems.
</p>
</div>
</section>

{/* Projects */}
<section className="py-20 px-4">
<div className="max-w-6xl mx-auto">
<h2 className="text-h1 mb-12">Selected Work</h2>
<div className="space-y-16">
<ProjectCard
title="SaaS Dashboard"
description="Complete redesign of enterprise analytics platform"
image="/project1.jpg"
/>
<ProjectCard
title="Mobile Banking App"
description="Consumer banking experience for Gen Z"
image="/project2.jpg"
/>
</div>
</div>
</section>
</div>
)
}

function ProjectCard({ title, description, image }) {
return (
<div className="grid md:grid-cols-2 gap-8 items-center">
<img
src={image}
alt={title}
className="w-full rounded-lg shadow-lg"
/>
<div>
<h3 className="text-project-title mb-4">{title}</h3>
<p className="text-body text-gray-600 mb-6">{description}</p>
<a href="#" className="text-body font-medium text-blue-600 hover:underline">
View Case Study →
</a>
</div>
</div>
)
}

Next Steps