Demystifying styled-components

Demystifying styled-components

Demo Post

When I first started using styled-components, it seemed like magic ✨. Somehow, using an obscure half-string-half-function syntax, the tool was able to take some arbitrary CSS and assign it to a React component, bypassing the CSS selectors we've always used.

Like so many devs, I learned how to use styled-components, but without really understanding what was going on under the hood. Knowing how it works is helpful. You don't need to understand how cars work in order to drive, but it sure as heck helps when your car breaks down on the side of the road.

Debugging CSS is hard enough on its own without adding in a layer of tooling magic! By demystifying styled-components, we'll be able to diagnose and fix weird CSS issues with way less frustration. In this blog post, we'll pop the hood and learn how it works by building our own mini-clone of đź’… styled-components.

Intended audience

This article is written for experienced React developers. I assume knowledge about React, styled-components, and functional programming principles. There's some pretty gnarly stuff in this one. I've done my best to simplify things, but there's no getting around it: this stuff is complicated.

The big idea

Let's start with a minimal example, taken from the official docs:

jsx
loading...

styled-components comes with a collection of helper methods, each corresponding to a DOM node. There's h1, header, button, and dozens more (they even support SVG elements like line and path!). The helper methods are called with a chunk of CSS, using an obscure JavaScript feature known as “tagged template literals”. For now, you can pretend that it's written like this:

jsx
loading...

h1 is a helper method on the styled object, and we call it with a single argument, a string. These helper methods are little component factories. Every time we call them, we get a brand-new React component. Let's sketch this out:

jsx
loading...

When we run const Title = styled.h1(...), the Title constant will be assigned to our NewComponent component. And when we render the Title component in our app, it'll produce an <h1> DOM node.

What about the styles parameter that we passed to the h1 function? How does it get used? When we render the Title component, a few things happen:

We come up with a unique class name by hashing styles into a seemingly-random string, like dKamQW or iOacVe.

We run the CSS through Stylis, a lightweight CSS preprocessor.

We inject a new CSS class into the page, using that hashed string as its name, and containing all of the CSS declarations from the styles string.

We apply that class name to our returned HTML element

Here's what that looks like in code:

jsx
loading...

If we render <Title>Hello World</Title>, the resulting HTML will look something like this:

html
loading...
Kartik Thakur
Author
Kartik Thakur
a front-end developer.

Comments