Creating a Typography System With React and styled-components

Jacy Clare
Jul 18, 2018 · 5 min read
Image by Damian Adrian / CC-BY-SA-3.0

The Problem

When working on an existing website, one normally doesn’t put too much thought in to how the typography might work, where the styles come from, or where the fonts are stored. However, when building something from scratch, all these questions need to be answered. When we got to this point, we had a functional site with 12pt Times New Roman for all the copy. In order to implement the designs and have a site that will make people go 😍 instead of 🤮, we needed a solution for the type that would accomplish three things:

  • Make it easy for us as developers to use
  • Enable consistent type across the site
  • Provide a maintainable formula for future developers when they do end up having to reason about typography in an existing system

First Pass — Typography.js

Incorporating styled-components

As you can see, this approach allows us to specify any tag we want as long as it’s present in theTagProps type. If you’re not familiar with typing in Javascript, you can read about Flow here. Additionally, it’ll pass along any props we supply and render any children we furnish. You might be thinking, “This is all great and dandy, but we still don’t have any typography styles!” And you’d be right, but this lays the foundation to build typography styles on top of DynamicComponent, like so:

This allows us to create a component for each style of type required, wrap a DynamicComponent in it, and render any HTML text element with any style we desire, while preserving corresponding props and children. Additionally, we export just the CSS styles so we can apply them in other situations where styled-components doesn’t work, like our StripeElements form.

Great! We’re done!

Component Bloat

Clearly this isn’t easy to grok or maintainable in the long run. We had failed in two of the three objectives of this endeavor.

Responsive Woes

While this solves the responsive problem, it only adds to the bloat problem, as we now have to create a new component for each time we need new responsive behavior.

Font Size as Props

Additionally, we can pass font sizes for different screen sizes and still use the media query in the components to render text responsively.

Hopefully this will be the one solution to rule them all.

One solution to rule them all, One solution to find them; One solution to bring them all and in the JavaScript bind them. Image by idreamlikecrazy / CC-BY-2.0

Conclusion

Interested in working with us? We’re hiring!

Harry's Engineering

The engineering blog of Harry's