A powerful React hook that automatically adjusts font size to fit text within its container. Perfect for responsive typography that scales beautifully across different screen sizes and container dimensions.
- ð Automatic font sizing - Text scales to fit perfectly within container bounds
- ð Responsive by default - Uses ResizeObserver for real-time container changes
- âĄïļ High performance - Optimized with requestAnimationFrame and binary search algorithm
- ð Flexible fit modes - Fit to width, height, or both dimensions
- ð Multi-line support - Works seamlessly with single-line and multi-line text
- âąïļ Debounced updates - Configurable debounce for smooth performance
- ðŊ TypeScript support - Fully typed with comprehensive type definitions
- ðŠķ Lightweight - Minimal bundle size with zero dependencies
npm install react-use-fittext
yarn add react-use-fittext
pnpm add react-use-fittext
import { useFitText } from 'react-use-fittext';
function ResponsiveText() {
const { containerRef, textRef, fontSize } = useFitText();
return (
<div
ref={containerRef}
style={{
width: '300px',
height: '200px',
border: '1px solid #ccc',
padding: '16px'
}}
>
<div ref={textRef}>
This text will automatically resize to fit!
</div>
</div>
);
}
function SingleLineExample() {
const { containerRef, textRef } = useFitText({
lineMode: 'single',
minFontSize: 12,
maxFontSize: 60
});
return (
<div ref={containerRef} className="banner">
<h1 ref={textRef}>BREAKING NEWS</h1>
</div>
);
}
function WidthOnlyExample() {
const { containerRef, textRef } = useFitText({
fitMode: 'width',
maxFontSize: 48
});
return (
<div ref={containerRef} style={{ width: '100%', maxWidth: '600px' }}>
<p ref={textRef}>
This text will scale based on container width only,
allowing vertical overflow if needed.
</p>
</div>
);
}
function PerformanceExample() {
const { containerRef, textRef, fontSize } = useFitText({
debounceDelay: 50, // Faster response
resolution: 1, // Higher precision
minFontSize: 8,
maxFontSize: 120
});
return (
<div ref={containerRef} className="dynamic-container">
<span ref={textRef}>
Current font size: {fontSize}px
</span>
</div>
);
}
function DynamicContentExample() {
const [text, setText] = useState('Initial text');
const { containerRef, textRef } = useFitText({
fitMode: 'both',
debounceDelay: 100
});
return (
<div>
<input
value={text}
onChange={(e) => setText(e.target.value)}
placeholder="Type to see text resize..."
/>
<div ref={containerRef} className="text-container">
<div ref={textRef}>{text}</div>
</div>
</div>
);
}
Property | Type | Default | Description |
---|---|---|---|
minFontSize |
number |
1 |
Minimum font size in pixels |
maxFontSize |
number |
100 |
Maximum font size in pixels |
resolution |
number |
0.5 |
Precision of the binary search algorithm (lower = more precise) |
fitMode |
'width' | 'height' | 'both' |
'both' |
Which dimensions to fit the text into |
lineMode |
'single' | 'multi' |
'multi' |
Whether to allow text wrapping |
debounceDelay |
number |
100 |
Debounce delay in milliseconds for resize events |
Property | Type | Description |
---|---|---|
containerRef |
RefObject<HTMLElement> |
Attach to the container element |
textRef |
RefObject<HTMLElement> |
Attach to the text element |
fontSize |
number |
Current calculated font size in pixels |
Text scales to fit within both width and height constraints of the container.
Text scales based only on container width. Height can grow as needed.
Text scales based only on container height. Width can grow as needed.
Allows text to wrap across multiple lines. Text will break naturally at word boundaries.
Forces text to remain on a single line. Long text will be truncated with ellipsis if it exceeds container width.
-
Adjust
debounceDelay
- Lower values (50-100ms) for faster response, higher values (200-300ms) for better performance -
Tune
resolution
- Use1
for pixel-perfect sizing,0.5
for good balance,2-3
for faster calculations -
Choose appropriate
fitMode
- Use'width'
or'height'
instead of'both'
when you only need single-axis fitting -
Set reasonable bounds - Use
minFontSize
andmaxFontSize
to prevent extreme scaling
const { containerRef, textRef } = useFitText({
lineMode: 'single',
fitMode: 'width',
minFontSize: 14,
maxFontSize: 24
});
const { containerRef, textRef } = useFitText({
fitMode: 'both',
minFontSize: 32,
maxFontSize: 96,
debounceDelay: 50
});
const { containerRef, textRef } = useFitText({
lineMode: 'single',
fitMode: 'width',
minFontSize: 10,
maxFontSize: 16
});
Text not resizing?
- Ensure the container has defined dimensions (width/height)
- Check that both
containerRef
andtextRef
are properly attached - Verify the container is visible in the DOM
Performance issues?
- Increase
debounceDelay
to reduce calculation frequency - Increase
resolution
for faster (but less precise) calculations - Consider using
fitMode: 'width'
or'height'
instead of'both'
Text overflowing?
- Check that container has
overflow: hidden
if needed - Ensure
minFontSize
isn't too large for the container - Verify container padding is accounted for in your layout
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
MIT ÂĐ akozma89