Photo by russn_fckr on Unsplash

Styling React Components

Why I chose glamorous

Cole Bemis

--

TL;DR

My goal was to find a maintainable and scalable way to style React components at iFixit. These were the features I was looking for in a React styling system:

  • Styles encapsulated within components
  • Local by default
  • Ability to delete code with confidence
  • Style as a function of state
  • Support for shared constants (color, spacing, etc.)
  • Ability to use native CSS features (media queries, animations, etc.)

I chose to use glamorous, a React styling library, because it addresses all of my wish list items with a simple API.

Goal

To find a maintainable and scalable way to style React components.

Wish List

These were the features I was looking for in a React styling system:

Styles encapsulated within components

I should not have to worry about how a component is styled in order to use that component. Using a component should be as easy as import MyComponent from ‘./MyComponent’. This means that I won’t have to sync up css files when using components (yay!).

Local by default

Native CSS is global by default. Global styles work great for styling documents but can create problems when styling large web applications. To deal with globals in CSS right now, we have to make sure our class names are specific enough to avoid naming collisions. Naming collisions due to global CSS class names result in unpredictable styling and are hard to debug and fix.

I want the styles I write to be locally scoped to the component I’m developing. This means that I can be confident that my styles won’t bleed into components.

It is really crazy to me that the best practices in CSS is still to use global variables. We’ve learned in JS for a long time that globals are bad.

– Christopher Chedeau, Front-end Engineer at Facebook

Ability to delete code with confidence

I should be able to confidently delete styles and know that I’m not going to break anything I didn’t expect. This will make the code way more maintainable.

Style as a function of state

The typical way we handle state-dependent styling at iFixit is to define state-specific classes (e.g. .button-disabled) and apply that class to an element conditionally with JavaScript. This method works for simple cases but it can get complicated for more involved use cases. Ideally, I could define the style of a component as a function of the component’s state. This is similar to the way React renders the view as a function of the application state. Here’s an article explaining this concept:

Support for shared constants (color, spacing, etc.)

Site-wide constant values like colors, spacing, font sizes, breakpoints, etc. should be available to any component. A component should be able to import the constants like this: import { colors } from ‘./constants’. This will enforce visual consistency and limit the number of decisions I have to make while developing.

Ability to use native CSS features (media queries, animations, etc.)

We don’t want to lose any feature that we have now. We still want to be able to use native CSS features like:

  • Media queries
  • Pseudo classes (e.g. :hover)
  • Pseudo elements (e.g. ::before)
  • Relational CSS Selectors
  • Animations

Conclusion

After exploring a blackhole of articles and videos, I decided to use glamorous to style React components. Glamorous is a React styling library with a simple API. The project is open source and maintained by Kent C. Dodds, an engineer at PayPal. Here’s how glamorous addresses all the items on my wish list:

✅ Styles encapsulated within components

With glamorous, styles are defined in the same file as the component. This makes it easy to develop and maintain components because all the relevant code is bundled in the same file.

Here’s an example of a simple Button component styled with glamorous:

Notice that using the Button component is super simple. No need to handle any separate CSS files.

✅ Local by default

Glamorous uses glamor to generate unique class names under the hood so we can be confident that our component styles are locally scoped.

✅ Ability to delete code with confidence

Because all of our component styles are local, we can be confident when deleting code that we won’t affect any other parts of the app.

✅ Style as a function of state

Glamorous allows us to define styles as a function of the state, like this:

props => ({ color: props.disabled ? ‘red’ : ‘blue’ })

This method is a lot more declarative than conditionally applying classes. Here’s an example of using dynamic styles with our Button component:

✅ Support for shared constants (color, spacing, etc.)

We can use simple JS constants to share values like color, spacing, etc. Here’s an example Button component using shared constants:

Notice that we’re just using plain JS to handled shared constants.

✅ Ability to use native CSS features (media queries, animations, etc.)

Glamorous allows us to use all the CSS features we know and love. Check out the Getting Started guide for examples.

Helpful Links

React: CSS in JS

These slides are kind of famous for changing the way we think about CSS. Check this out if you’re thinking: “Why would anyone want to write CSS in JS? What a terrible idea!”

Choosing a CSS in JS library

This is a good overview of all the ways to style React components. Check this out if you’re thinking: “What are the alternatives to glamorous?”

Getting Started with Glamorous

Check this out if you’re thinking: “Glamorous seems cool. How do I get started?”

Have a question or comment? Let’s talk on Twitter: @colebemis

--

--

Cole Bemis

Building things for people who build things. Design Systems Engineer at GitHub. Studying Computer Science at CalPoly.