Fluid Responsive Design - Typography
Unlock advanced capabilities with styleframe Pro. This feature requires a Pro license to access.
Upgrade to ProOverview
The useFluidFontSize() composable creates complete fluid typography systems that scale smoothly across all viewport sizes. It combines base font size ranges with modular scale multipliers to generate type hierarchies that maintain perfect proportions from mobile to desktop.
Unlike traditional responsive typography that jumps between fixed sizes at breakpoints, fluid typography creates smooth, continuous transitions that look perfect at every viewport width.
Why use fluid typography?
Fluid typography helps you:
- Eliminate breakpoint jumps: Text scales smoothly instead of jumping between fixed sizes at media queries.
- Maintain perfect proportions: Use modular scales to ensure harmonious relationships at every viewport width.
- Reduce code complexity: Define your entire type system once instead of managing multiple breakpoints.
- Improve readability: Automatically optimize text size for the available space.
- Create responsive hierarchies: Scale relationships between different text sizes remain consistent.
useFluidFontSize()
The useFluidFontSize() composable generates a complete set of fluid font size variables based on base size ranges and modular scale multipliers.
import { styleframe } from 'styleframe';
import { useScale, useScalePowers, defaultScaleValues } from '@styleframe/theme';
import { useFluidViewport, useFluidFontSize } from '@styleframe/pro';
const s = styleframe();
// Set up fluid viewport range (320px - 1440px)
useFluidViewport(s);
// Define scales for mobile and desktop
const { scaleMin, scaleMax } = useScale(s, {
...defaultScaleValues,
min: '@minor-third', // Minor Third scale for mobile
max: '@major-third' // Major Third scale for desktop
});
// Calculate scale powers
const scaleMinPowers = useScalePowers(s, scaleMin);
const scaleMaxPowers = useScalePowers(s, scaleMax);
// Generate fluid font sizes
const {
fontSize,
fontSizeXs,
fontSizeSm,
fontSizeMd,
fontSizeLg,
fontSizeXl,
} = useFluidFontSize(s,
{ min: 16, max: 18 }, // Base font size range
{
xs: { min: scaleMinPowers[-2], max: scaleMaxPowers[-2] },
sm: { min: scaleMinPowers[-1], max: scaleMaxPowers[-1] },
md: { min: scaleMinPowers[0], max: scaleMaxPowers[0] },
lg: { min: scaleMinPowers[1], max: scaleMaxPowers[1] },
xl: { min: scaleMinPowers[2], max: scaleMaxPowers[2] },
default: '@md'
}
);
export default s;
:root {
--fluid--min-width: 320;
--fluid--max-width: 1440;
--fluid--screen: 100vw;
--fluid--breakpoint: calc(...);
--font-size--min: 16;
--font-size--max: 18;
--font-size--xs: calc(...);
--font-size--sm: calc(...);
--font-size--md: calc(...);
--font-size--lg: calc(...);
--font-size--xl: calc(...);
--font-size: var(--font-size--md);
}
useFluidViewport() before using useFluidFontSize(). The fluid font size composable relies on the fluid breakpoint variables created which are picked up automatically.Understanding the Parameters
The useFluidFontSize() composable accepts three main parameters:
1. Base size range - Define minimum and maximum font sizes:
{ min: 16, max: 18 } // Base text scales from 16px to 18px
2. Size definitions - Define which scale power each size should use. The base size range will be multiplied by these powers to create each font size:
{
xs: { min: scaleMinPowers[-2], max: scaleMaxPowers[-2] },
sm: { min: scaleMinPowers[-1], max: scaleMaxPowers[-1] },
md: { min: scaleMinPowers[0], max: scaleMaxPowers[0] },
lg: { min: scaleMinPowers[1], max: scaleMaxPowers[1] },
xl: { min: scaleMinPowers[2], max: scaleMaxPowers[2] },
}
3. Custom breakpoint (optional) - By default, references the fluidBreakpoint variable from useFluidViewport(). You can override the default fluid breakpoint:
const { fluidBreakpoint } = useFluidViewport();
useFluidFontSize(s, { min: 16, max: 18 }, sizes, customBreakpoint);
Understanding Modular Scales
Modular scales create harmonious proportions by multiplying a base value by consistent ratios. The scale ratio determines how dramatically your font sizes grow.
Common Scale Ratios
| Scale Name | Ratio | Character | Best For |
|---|---|---|---|
| Minor Second | 1.067 | Very subtle | Minimal designs, tight hierarchies |
| Major Second | 1.125 | Subtle | Clean, understated designs |
| Minor Third | 1.2 | Balanced | Most websites, readable hierarchies |
| Major Third | 1.25 | Distinct | Marketing sites, clear hierarchy |
| Perfect Fourth | 1.333 | Bold | Editorial content, strong contrast |
| Perfect Fifth | 1.5 | Dramatic | Landing pages, hero sections |
| Golden Ratio | 1.618 | Striking | Art, design-forward sites |
Choosing Scale Ratios
Choose different scales for mobile and desktop to optimize readability at different viewport sizes:
// Subtle on mobile, balanced on desktop
import { useScale, defaultScaleValues } from '@styleframe/theme';
const s = styleframe();
// Define scales for mobile and desktop
const { scaleMin, scaleMax } = useScale(s, {
...defaultScaleValues,
min: '@minor-third', // Minor Third scale for mobile
max: '@major-third' // Major Third scale for desktop
});
Using Fluid Typography Variables
Once created, fluid typography variables can be applied to elements just like regular CSS variables:
import { styleframe } from 'styleframe';
import { useScale, useScalePowers, defaultScaleValues } from '@styleframe/theme';
import { useFluidViewport, useFluidFontSize } from '@styleframe/pro';
const s = styleframe();
// Set up fluid viewport range (320px - 1440px)
useFluidViewport(s);
// Define scales for mobile and desktop
const { scaleMin, scaleMax } = useScale(s, {
...defaultScaleValues,
min: '@minor-third', // Minor Third scale for mobile
max: '@major-third' // Major Third scale for desktop
});
// Calculate scale powers
const scaleMinPowers = useScalePowers(s, scaleMin);
const scaleMaxPowers = useScalePowers(s, scaleMax);
// Generate fluid font sizes
const {
fontSize,
fontSizeXs,
fontSizeSm,
fontSizeMd,
fontSizeLg,
fontSizeXl,
fontSize2xl,
} = useFluidFontSize(s,
{ min: 16, max: 18 }, // Base font size range
{
xs: { min: scaleMinPowers[-2], max: scaleMaxPowers[-2] },
sm: { min: scaleMinPowers[-1], max: scaleMaxPowers[-1] },
md: { min: scaleMinPowers[0], max: scaleMaxPowers[0] },
lg: { min: scaleMinPowers[1], max: scaleMaxPowers[1] },
xl: { min: scaleMinPowers[2], max: scaleMaxPowers[2] },
'2xl': { min: scaleMinPowers[3], max: scaleMaxPowers[3] },
default: '@md'
}
);
// Apply to semantic elements
selector('body', {
fontSize: ref(fontSize),
});
selector('small', {
fontSize: ref(fontSizeSm),
});
selector('h3', {
fontSize: ref(fontSizeLg),
});
selector('h2', {
fontSize: ref(fontSizeXl),
});
selector('h1', {
fontSize: ref(fontSize2xl),
});
export default s;
:root {
--fluid--min-width: 320;
--fluid--max-width: 1440;
--fluid--screen: 100vw;
--fluid--breakpoint: calc(...);
--font-size--min: 16;
--font-size--max: 18;
--font-size--sm: calc(...);
--font-size--md: calc(...);
--font-size--lg: calc(...);
--font-size--xl: calc(...);
--font-size--2xl: calc(...);
--font-size: var(--font-size--md);
}
body {
font-size: var(--font-size);
}
small {
font-size: var(--font-size--sm);
}
h3 {
font-size: var(--font-size--lg);
}
h2 {
font-size: var(--font-size--xl);
}
h1 {
font-size: var(--font-size--2xl);
}
Best Practices
- Choose appropriate base size range: Keep body text scaling subtle for better readability. 16px to 18px (12.5% increase) is ideal. Avoid extreme ranges like 12px to 20px (67% increase) which harm readability.
- Use consistent scale ratios: Stick to proven modular scales. Common combinations include Minor Third to Major Third (1.2 to 1.25), or Minor Third to Perfect Fourth (1.2 to 1.333).
- Ensure mobile scale is smaller than or equal to desktop scale.
- Always call
useFluidViewport()first: The other fluid composables depend on fluid breakpoint variables. - Limit the number of font sizes: Aim for a smaller number distinct sizes to maintain clear hierarchy without creating confusion. Too many sizes (12+) lead to inconsistency.
- Test at multiple viewports: Verify typography at mobile, tablet, and desktop sizes. Ensure body text remains readable with 45-75 characters per line.
FAQ
useFluidFontSize()creates a complete typography system with multiple related sizes using modular scales. It's specifically designed for font sizes and handles scale power calculations.useFluidClamp()creates a single fluid value between a min and max, and is more general-purpose for any CSS property.
Use useFluidFontSize() for typography systems, useFluidClamp() for individual values like spacing or border radius.
useFluidFontSize(), then create a separate system with a dramatic scale (1.333 to 1.5) for display text. Each system can have its own base size range and scale powers, giving you fine-grained control over different typography contexts.useFluidFontSize() for scalable sizes with useFontSize() for fixed sizes. For example, use useFluidFontSize() to create fluid heading sizes that scale smoothly, while using useFontSize() for fixed body and UI text that stays consistent. This gives you the benefits of fluid scaling where it matters most (large display text) while maintaining predictability for smaller text.useLineHeight() to get consistent ratios like lineHeightTight (1.25), lineHeightNormal (1.5), and lineHeightRelaxed (1.75). When you apply these to elements with fluid font sizes, the line height automatically scales proportionally, maintaining readable spacing at all viewport sizes without additional calculations.useFluidFontSize() with useFontFamily() and useFontWeight() to create sophisticated typography systems. Variable fonts offer the added benefit of smooth weight transitions and optical sizing adjustments that complement the fluid scaling, resulting in even better typographic quality across viewport sizes.useFluidViewport(s, { minWidth: 375, maxWidth: 1920 }) if needed. The key is choosing a range that matches your actual user viewport distribution.Next Steps
- Clamp Function: Learn about
useFluidViewport()anduseFluidClamp() - Scales: Deep dive into modular scales and scale powers
- Typography: Explore fixed typography composables
- Line Height: Create proportional line heights
- Utopia Fluid Type Scale: Explore the mathematical foundation behind fluid typography