Fine-Tune Your Font Sizes in React with the useFontSize Hook
Learn how to optimize font sizes in React for better accessibility and user experience with the useFontSize custom hook.
Following the first article about React Custom Hooks, today we’ll see how to simplify and reuse across our apps another piece of logic, enhancing our skills as React developers little by little. I’m talking about the useFontSize custom hook, let’s see together why is it so useful!
Why the need for a useFontSize hook?
Using the Medium app on my smartphone, I was navigating through the app’s options while reading, and I crossed a pretty nice feature: Medium gives you the ability to resize the font size of the app to help you read better posts’ content.
This is a pretty common feature in many platforms, but I never thought of implementing it, not even for learning purposes.
So, to implement the functionality on this website, I came up with this custom hook that allows me to control a CSS variable. This way I can then use this variable in my text components and obtain a full font resize feature without rendering all the text components (more on this in the future, maybe with a new article 😁).
How does it work?
This custom hook comes with some features:
- Set a CSS variable into the document element. The variable name can be customized.
- Store the saved value in the localStorage, so that our users are not required to change the font size on every page reload.
- The hook is isomorphic, which means it works also doing Server Side Rendering.
The hook accepts some optional parameters to customize its functioning, such as the localStorage key to store the font size, the CSS variable name and the initialSize in case of SSR.
The implementation
Here you go with the code implementation! I know it’s a long piece of code, but most of it is comments I left to clarify what it does, so let’s read the code and let’s check together what’s going on behind the scene! 🚀
Now let’s see what’s happening step by step:
First of all, it imports utilities and hooks necessary for the implementation, you can find all of them in the mountain-ui repository.
The next step is to define an interface to describe the 3 accepted options: storageKey, initialSize and variableName. If you are not using typescript, you can skip this step.
It’s time to declare some utilities to set and retrieve the font-size variable from the
<html>
node inside the DOM. The two functions applyPropToDocument and getDocumentProp respectively do those operations.We are finally ready to start declaring the custom hook! We’ll destructure from the options object the previously defined parameters, assigning default values in case their not passed when using the hook.
At the beginning of the implementation, the hook invokes another custom hook, the useLocalStorage utility, you can deeply read about it in my previous post about this hook.
As you can read in the code comment, it creates a React state connected to the localStorage, so it can fulfill the requirements we’ve seen before.Since we are going to use the useReducer hook for this implementation, it was necessary to define the init function that will take care of various detail once the hook is invoked the first time:
- Check if the hook runs in the client, otherwise return the default value.
- If a font size is already stored in the localStorage, set it as a CSS variable.
- Return the stored value as the state value.
The last step before returning the useReducer result is to define the necessary logic to update the font-size value and store it in the localStorage and notify the component about the change. All this logic goes inside the reducer function.
How to use the useFontSize hook?
Attached at the end of the gist you’ll find a basic example of how to use the custom hook, but this should not limit your imagination on how to make the user interact with your page! On my website, I made it interactive through a slider!
Conclusion
We are at the end of this second React Hooks story, I hope it could be helpful and I’d like to hear from you for any doubt!
You can also find more about the resources I’m using on the following pages:
Thanks for taking the time to read it, see you with the next post! 🚀
Last updated: