FitText.js as a React v16+ component, and now in TypScript!
If you want to make specific text fit within a container, and then maintain that ratio across screen sizes, this component is for you.
FitText is a particularly useful approach for:
- Predetermined content (ie. not user generated or dynamic)
- Text that fits within a container until it hits a minimum or maximum font size, and then reflows normally from there
- Multi-line text that fits
This component is written specifically for React v16 and up, includes tests, and uses state to avoid DOM manipulation.
The existing React FitText component by @gianu should still work with current versions of React, and is stateless, but manipulates the DOM directly to change font sizes.
The approach I’m using feels more React-appropriate, at least to me. I use this component regularly enough that it made sense for me to maintain my own version regardless.
yarn add @hoonsubin/react-fittext
or
npm install --save @hoonsubin/react-fittext
import FitText from '@hoonsubin/react-fittext';
<FitText compressor={0.5}>The quick brown fox jumps over the lazy dog.</FitText>
With multiple children:
<FitText compressor={0.5}>
<>
<h2>Pangram</h2>
<p>The quick brown fox jumps over the lazy dog</p>
</>
</FitText>
From the original FitText.js documentation:
If your text is resizing poorly, you'll want to turn tweak up/down “The Compressor.” It works a little like a guitar amp. The default is
1
. —davatron5000
<FitText compressor={3}>The quick brown fox jumps over the lazy dog.</FitText>
<FitText compressor={1}>The quick brown fox jumps over the lazy dog.</FitText>
<FitText compressor={0.3}>The quick brown fox jumps over the lazy dog.</FitText>
<FitText compressor={0.5} minFontSize={24} maxFontSize={96}>
The quick brown fox jumps over the lazy dog.
</FitText>
Change the included debounce resize timeout. How long should React FitText wait before recalculating the fontSize
?
<FitText debounce={3000} compressor={0.5}>
The very slow brown fox
</FitText>
The default is 100
milliseconds.
React FitText needs the viewport size to determine the size the type, but you might want to provide an explicit fallback when using server-side rendering with React.
<FitText defaultFontSize={100} compressor={0.5}>
The quick brown fox
</FitText>
The default is inherit
, so typically you will already have a resonable fallback without using this prop, using CSS only. For example:
.headline {
font-size: 6.25rem;
}
<div className="headline">
<FitText compressor={0.5}>The quick brown fox</FitText>
</div>
Add the vertical
prop to scale vertically, rather than horizontally (the default).
<div style={{ height: '75vh' }}>
<FitText vertical compressor={1.25}>
<ul>
<li>Waterfront</li>
<li>Vancouver City Centre</li>
<li>Yaletown–Roundhouse</li>
<li>Olympic Village</li>
<li>Broadway–City Hall</li>
<li>King Edward</li>
<li>Oakridge–41st Avenue</li>
<li>Langara–49th Avenue</li>
<li>Marine Drive</li>
</ul>
</FitText>
</div>
Use a different parent, other than the immediate parentNode
, to calculate the vertical height.
<div id="js-example">
<AnotherThing>
<FitText vertical parent="js-example">
{dynamicChildren}
</FitText>
</AnotherThing>
</div>
<div>
<div style={{ height: '1000px' }} ref={(el) => (this.parentNode = el)}>
<h1>A contrived example!</h1>
</div>
<FitText vertical parent={this.parentNode}>
{dynamicChildren}
</FitText>
</div>
To run the Storybook stories on your local machine:
git clone https://github.com/hoonsubin/react-fittext
cd react-fittext
# Install dependencies
yarn
# Run the project through Storybook
yarn storybook
- The original FitText.js by @davatron5000
- react-fittext by @gianu
- React v16+ component implementation by @kennethormandy
Apache License v2.0 (Apache-2.0)
Copyright © 2014 Sergio Rafael Gianazza
Copyright © 2017–2019 Kenneth Ormandy Inc.
Copyright © 2020 Hoon Kim