Why Aphrodite became our choice for styling React apps
I have been working with React since the start of my professional career to build web applications, and the web wouldn’t be the web without CSS.
In our company we’ve relied on JavaScript based styling for quite a while now. And when looking out there, JavaScript based styling seems to, fortunately, have become a new kind of standard. Personally I enjoy this change, using styles inside the JavaScript allows me to focus on writing the components and their behavior without having to worry about the problems of styling. More and more developers start adapting JavaScript based styling as a practice, and I often hear them saying, that it was long overdue we abandoned a more than 20 years old dogma of separating style and structure in web development. But we don’t do it seriously and we don’t need to. We are just starting to isolate our components and not writing an hilarious rule set, apart from them, of how they should materialize together.
One of the main reasons for this change is probably the fact that the web went away from just structured content, over MVC applications to pure “component based” single page applications. In this type of applications, components are designed with strong isolation in mind, and you should be able to drop a component anywhere in your application, trusting that as long as the props are the same, it will look and behave the same way. While you can read up a lot of pros on JavaScript based styling in Christopher Chedaeu’s presentation of React: CSS in JS, we also discovered several cons before using Aphrodite, that are mainly caused by the limitations of pure inline styles.
- Hard to read code when looking through basic inspection tools
- Animations, media queries and overriding nesting classes are not possible
- Integrating third party components isn’t easy since they aren’t usually agnostic to styling practice
These limitations led to a couple of hacks like having a special CSS file to write rules that only worked on classic CSS and to override certain properties from third party packages. This was not optimal so we started to take a look on alternatives to pure inline styling.
A couple of options stood out, amongst them JSS, Radium and Aphrodite. When taking a superficial look at JSS and Radium they seemed to be more robust, with access to custom plugins but at the same time also looked more complex, not exactly what we were looking for to start with, as we wanted something simpler but powerful at the same time. So we took a look at Aphrodite and must say that so far we have not been disappointed.
Aphrodite is developed by Khan Academy and their motto for this project is: “Aphrodite: Inline Styles that work”. You can see a bunch of features they support on their github but I will be showing some of the features we needed the most.
The syntax
For those of you who have worked with React-Native you can see that the syntax to create styles is similar to Facebook’s approach, we simply define the styles inside Aphrodite’s StyleSheet and we are good to go. When applying the styles simply use the “css” method from Aphrodite inside the className prop of the Component.
The main difference from basic inline styling would be the use of className prop instead of the style prop. But that is it, ready to go.
Animations
Building simple animations tends to be easier with CSS than with JavaScript and Aphrodite allows CSS animations out of the box. In this example I wanted a simple navigation bar to hide based on a prop passed to the component. I achieved this easily with the code below:
You can find some additional examples in the project’s github repository but you will notice the syntax will be the same. We simply define the keyframes we want and then the animation properties inside the style with the animation name referring to those keyframes.
Media queries
Media queries are the basic tool for responsive design and with inline styling this was not possible. With Aphrodite not only do we have that possibility, as it is really simple to do. We need only add a key to the class object we are defining inside the styles and we are set. Let's say I wanted to decrease the fontSize of some text when the screen size decreased to make better use of the space:
The declaration is exactly like in CSS we need only to set it as a key inside the class object of the styles constant and we are good to go.
Overriding nested classes
When building applications with React it is common to use third party packages that bring already made components to ease your life, but when trying to shape those components to your need you might find that they don’t bend easily. Some components bring their own CSS classes and you might need to override them, this is possible with Aphrodite but with a kind of a hack:
This would override the class “testClass” making the text “Action 1” green. Granted it is not the cleanest solution but it works and I only ever have to override classes from third party components so it shouldn’t see too much use in normal situations. You can find an explanation why this works like this here.
Readability
When dealing with inline styles it can be a mess to inspect the code and find the exact component you were looking for.
With Aphrodite the class names are generated so that they are unique but they will take into account the class name you gave them. This will make the code more structured and easier to read:
If you have a good naming system for your classes you are guaranteed to find what you are looking for, and in bigger projects this proved to be an important factor.
Final thoughts
We came across JavaScript based CSS, because of React-Native styling practices and decided to use them in React apps as well. There are amazing style guides to make your life easier and your styling more coherent like the AirBnB Style Guide. But to really get the best out of styling in the web we had to move to something more sophisticated and Aphrodite seems to be a good solution if you are looking for something simple with some power to get you going. It has solved a lot of issues we had, overriding styles of third party components and giving us an edge on media queries, plus its easy to use. That said I can see some of its limitations, the solution to override nested classes is not well supported and you might need a bit of pre-planning on class naming, surely there are some more that I have yet to come across.
We are still keeping an eye on alternatives and on the “market” of styling frameworks and who knows what the future might bring but so far I am really happy with Aphrodite, its simplicity has allowed me to write more coherent code, to detect UI bugs easily and to focus more on the architectural challenges of the applications and less on the styling.