Styling is a huge part of the user experience for your apps. You’ve got a new design and you’re going to build your new awesome app in
React. But how do you go about implementing that design?
It would be fair to say that
React is pretty popular. So it’s no surprise that there are a multitude of options when it comes to styling
React apps. There is no real right or wrong. It’s what feels best for you. The main decision will be going in or out. And by that I mean “CSS in JS” or “CSS out JS” 💅 Of course, if you’re styling a
React Native app, that decision has already been made for you.
For those in camp TL;DR, There are many options when it comes to styling your
React apps. Go with what feels best for you. Whether you go
CSS in or out, I recommend colocating styles with their components 🙏 Be open to trying out new techniques and packages. You might surprise yourself. For more on styling
React apps be sure to check out the Styling and CSS FAQ in the docs!
Before we dig into some of the options let’s consider structure and approach. We won’t dig into this too much I promise.
In general we should try to colocate styles with their respective components. This can make life a lot easier when your projects become complex. It’s also easier for those new to a project to understand where things live. If you’re opting to go the “
JS” route, then you can write your styles in the component file. I would recommend extracting styles into their own files though. Smaller files are going to be easier to read and digest; especially for newcomers to a project.
One approach I like is to use an extension prefix. Consider a
Nav component. I would create a folder for
Nav inside a
Components folder. I could then create
style.js/css. You could go a step further with
nav.style.js. This makes things like searching for a file with an IDE much easier in my experience.
Aside from structure, it should go without saying that it’s wise to try and reuse styles where possible. Extract common styles into their own stylesheets or modules. Consuming reusable patterns will reduce code bloat and make maintenance easier.
With that out of the way, let’s move onto our options! 👍
The main options fall into two categories.
CSS out of
JS. Both will work great!
Let’s start with
CSS. It’s likely to be your first port of call and what you’re familiar with. Using
CSS will entail assigning classes to your components using the
As with any project, you’ll want to spend some time considering appropriate classes. Opt for using a classing standard like
BEM. Not long into working with the
className prop, you’re likely to come across an issue. The issue being how to assign many classes based on
Array like this won’t work. You can use template literals of course.
You could also opt to use
Array.join if you wanted 👍
Alternatively, you might find more joy using the
classnames package 👍
Writing something like
Will give us
HTML that uses locally scoped classes
Although the majority of your app won’t be in the
DOM on load, that doesn’t mean
CSS performance rules don’t apply. You will still want to tackle render blocking
CSS. You can do this by inlining critical styles and only loading what’s necessary for the root of your app.
And that’s a great use case for utilising code splitting in your
React apps. With code splitting you will be able to do things like lazy load styles for routes within your app.
The alternative to
CSS out of
JS is to go
Whilst the majority of your styling is now defined in
JS, you will likely need to define some in
CSS. Inlining some critical styles and defining base styling will aid with page performance 👌 Unless you are using
SSR, there will still be a small delay between page load and app load. You can check performance for your app by running an
Audit through the developer tools in
You’ve opted to go
JS. You are now defining your styles within
Not only that, you will only create the styles you need and only load them when appropriate. You can even test your styles! There aren’t the only benefits.
At it’s simplest, through inline styling. But, this is not usually how
JS works. We are likely to use a third party package for our
JS. These packages will do the heavy lifting for us 💪 In most cases, these packages will take our style definitions and create class names for them. These styles are then inlined within a
style tag inside the
head of the page
document. A benefit to this approach being that we aren’t duplicating styles. It also makes the
DOM easier to inspect.
Here’s a very simple example using
AppHeading isn’t very useful here but there for demo purposes.
This would create a
h1 with a unique
class generated for it.
class name. A style rule will have been inlined 👍
Before digging into third party
JS, let’s roll back to creating it ourself to understand the core benefits.
The premise of
JS is exactly that. At it’s core, we define styling within
Objects or template literals. A basic example being to create a style definition and apply it inline to an element. Unfortunately, we can’t pass an
Objects but we can pass a merging of
In this example, two styles
large are imported. They are conditionally merged based on props.
How might those styles look? They could simply be as follows
Note, in most cases when defining styles within
camelCase. Numbers are likely to default to
Those styles don’t look very efficient do they? 👎
A major benefit of defining
JS is to be able to conditionally generate styles. We can refactor our styles into a function that returns the style for our component 💪
But, things are going to get pretty tedious pretty quick. That’s because we will be writing these styling functions over and over. And you’ll also have to keep up with maintaining them. You’re also inlining everything 😭
Luckily, there are some great third party packages to aid with handling
I don’t have experience with them all so I will be using
styled-components for these examples. It’s my personal favorite and the one I have most experience with 😅 But there are many options out there. Michele Bertoli has done a great job of curating them here 👏
Don’t worry though as I won’t dig too far into third party packages ⛏ This is because you’ll likely want to explore for yourself and create your own preference. We will run through a very simple example so we can see the benefits.
If you’d rather take a quick look at
styled-components before going any further, check it out here 👍 Don’t worry though, I will keep any examples intuitive and simple.
For a more thorough look at
styled-components, I’d strongly recommend watching this fantastic video
Let’s start simple. If we take our example from above, we could transform that into an
Emoji styled component.
Note how we are writing plain
CSS there 👍
styled-components uses tagged template literals to support all
CSS. You can create animations, use pseudo elements, everything is vendor prefixed for you!
For our example, it should be clear what’s happening here and how we could use it.
Want to make one larger? Boom 💣 It’s that easy.
You may notice something already. Not only do we get conditional styling but our styled component gives us context.
If we were to use
spans, we would lose that context. If we were to use our stateless inline
Emoji component from above, we wouldn’t get the maintenance benefits. Of course, with this example being very small, it’s may be hard to justify the switch. But think larger than that and you are likely to see the benefits.
Consider apps you have written that use several
divs within a component. Using a
JS solution, we not only get the power of
JS but we can provide context to smaller elements. Smaller elements whose sole purpose may be to provide style.
And to reiterate, this is important. We are able to separate styles from logic.
Consider the example of a sliding side bar navigation menu.
There’s a bit going on there already without looking at styling. But consider that our
CSS will have to contain styling for when the nav is open and closed 👎
styled-components we could create something more along the lines of
That is so much clearer 😍 Any styling declaration via
classNames are extracted and we are left with building blocks to create our component 👌
Container component may look like this
These styled components give us small manageable blocks to build our apps with.
Once you start digging into using
JS you start to sense its benefits. The power of
It’s worth mentioning
react-native apps and how you might style them. With
react-native, you’re going
JS. There is no notion of
className. Everything is inline through the
style property. But you can pass arrays of styles 😉
You’ll also get
StyleSheet. A helper for creating your
Which means you can tidy up a little like this
But if you wanted to have some consistency across platforms, you could continue with
styled-components! They have a native implementation which is pretty sweet if you ask me 👏
Giving you a nice clean component structure of
If you’ve made it this far, thanks for reading 🙌 It’s not the easiest subject to write about but I hope you gained something from it.
We’ve taken a look at the whole
CSS in or out of
JS topic. For web applications, there does seem to be a shift towards going
JS, at least for now. Regardless of which way you go you’ll still likely need to write or use some native
CSS at some point.
If you do find yourself making the switch, I recommend checking out
styled-components. It’s very easy to pick up.
As always, any questions or suggestions, please feel free to leave a response or tweet me 🐦!