An Introduction To Styled Components
React
28/11/2020
There are a couple of ways to style your React components. You may either choose to do inline styling, import your CSS from an external style sheet, or even include it in your JavaScript file. Particularly, in this article I will cover the last method with an introduction to the React library Styled Components. 💅 Let's get styling, mi amigos!
Why use Styled Components
Every library has its purpose and so does this one: improving the developer experience of styling React components! That's... kind of vague, right? 😅 So let's dig a bit deeper. What are its benefits?
- Only relevant CSS is loaded as the styling is bound to its own respective component. So for instance, if you have a web page that doesn't have any button (component), you will not find any CSS concerning buttons. Naturally, this translates into less code on your live site. As a counter example, imagine loading a single style sheet that contains all your CSS, even if the page you're on only uses a fraction of it.
- No more class name related bugs such as duplication and misspelling. Instead, class names are generated for you! 😎
- Dynamic styling based on
props
is a simple, yet powerful option that gives way to many possibilities. Easily one of my favorite reasons to use this library! - Easier maintenance of your CSS code since you know exactly where the styles affecting your components are.
- Automatic vendor prefixing... booyah! 🤩
The Basics
In order to use this library in your project, run either npm install --save styled-components
or yarn add styled-components
. Afterwards, import it into your pages with import styled from 'styled-components'
... you know the drill. 😉
Alright, time to dig into the code by taking a look at an example:
const Title = styled.h1` font-size: 1.5em; text-align: center; color: red;`;
In this code snippet, we declare a variable Title
as an H1
tag with some CSS using the imported object styled
and its method h1
. There is an equivalent method for every HTML tag you can think of, e.g. p
, button
, section
, div
, etc. However, what follows afterwards with the back ticks ``
may seem strange to some of you. 🤨 Many of you have probably seen it in the context of multi line strings. This feature is called template literals, or template strings, and was introduced with ES6.
Unfortunately, I won't be going into the details as its functionality merits a blog post of its own. However, for those who need to quench their undesirable thirst for JS knowledge, I recommend the blog post The magic behind styled-components by Max Stoiber 😁. For the... uhm, laid back people of us, here's what you can take away: the string in back ticks is actually passed as an argument to the function h1
, which then parses its content and transforms it to pure CSS, including any JavaScript from interpolations (i.e. ${}
).
Next, Title
can be used as any other React component you're used to.
render( <div> <Title> All Hail Chunk Bytes! </Title> </div>);
Dynamic Styling
One powerful feature of Styled Components is its ability to allow for styling based on props you pass to it. Let's build on the previous example, shall we?
<Title primary> All Hail Chunk Bytes!</Title>
Remember, passing the props primary
without a value, is the equivalent to primary={true}
. This props is then available in our template literal through interpolation.
const Title = styled.h1` font-size: 1.5em; text-align: center; color: ${props => props.primary ? "red" : "black"};
// Or with destructuring: color: ${({ primary }) => primary ? "red" : "black"};`;
For the CSS property color
, we check if primary
exists and then set the respective color accordingly. We do this IF
statement with the help of a ternary operator. However, this isn't only restricted to one property. You may even conditionally render multiple CSS properties depending on the prop. 👆
import styled, { css } from 'styled-components'
const Title = styled.h1` font-size: 1.5em; text-align: center; color: red;
${({ primary }) => primary && css` color: red; text-align: left; `};`;
In the example above, we load two additional properties if primary
exists. However, to be able to use a template literal inside an interpolation, we need to import and use the function css
. [Insert template literal Inception joke here] 😆
Reusing styled components
Don't Repeat Yourself - The philosophy all coders (hopefully) love to follow, and this isn't any different here! Styled Components allows us to reuse existing components and apply another layer of styling on top. Let's work with the most recent example, but implement the changes for a primary
title another way.
const PrimaryTitle = styled(Title)` color: red; text-align: left;`;
Et voilá! 🥐 We created another component called PrimaryTitle
using Title
and its styling as the base. For this, we simply need to pass it as an argument to styled
.
Good to know
Before this tutorial comes to an end, there are a couple more things I'd like to show you that will really supercharge your Styled Components in your future project.
Pseudo-classes, elements and nesting
const Title = styled.h1` font-size: 1.5em; text-align: center; color: red;
&:hover { color: blue; }`;
You can apply pseudo classes and elements, by taking advantage of the ampersand (&), much like in Sass. Even better, you can nest your CSS logic just like in Sass. But don't got crazy! 😝
In case you're curious what other (S)CSS features Styled Components has to offer, I recommend checking out the preprocessor Stylis, which this library is based on.
Substituting the tag
What if I want to make the H1 component from our examples an H2? Easy peasy! Just pass your desired HTML tag as a props with as
.
<Title primary as='h2'> All Hail Chunk Bytes!</Title>
Adding a theme
No coding project is complete without its own theme. Keep it DRY, remember? Styled Components provides a wrapper component called ThemeProvider
. Via the Context API from React, it propagates your theme through all its children 👶 in the application. The theme can then be accessed via props in the styled component.
import styled, { ThemeProvider } from 'styled-components'
const Title = styled.h1` font-size: 1.5em; text-align: center; color: ${({ theme }) => theme.colors.blue};`;
const theme = { colors: { blue: '#4064d7' }};
render( <ThemeProvider theme={theme}> <Title> All Hail Chunk Bytes! </Title> </ThemeProvider>);
Hopefully this introduction to Styled Components has shown you the power of writing CSS in JavaScript and its possibilities. Maybe after this, you'll even become addicted to this way of writing CSS. 😂