Styling React with Emotion

joshtronic

Out of the box, React allows you to style components directly with the style property. It’s accepts an object of style properties and for most use cases, it’s more than sufficient. As a single property, there’s no way to specify more granular defaults and support for !important is effectively non-existent with the style property. Luckily, a bit of emotion will go a long way!

👩‍🎤 emotion is flexible and highly performant CSS-in-JS library. It accepts strings and objects, supports defaulting and extending variable and with an additional Babel plugin even supports inline child selectors!

Getting Started

To kick things off, we will need to install our dependencies, emotion and emotion-react via npm:

$ npm install --save emotion emotion-react

or via yarn:

$ yarn add emotion emotion-react

Be sure to include react-emotion within in your component’s source code:

import styled, { css } from "react-emotion";

Usage

With our dependencies installed, let’s talk about the different ways that you can leverage emotion to style your components.

CSS

The quickest way to get up and running with emotion is by passing css to an element’s or component’s className property.

css accepts styles as a string, a tagged template literal, an object or an array.

Here are a couple of examples of css with a string and with an object:

<div className={css`background: #eee;`}>
  <div className={css({ padding: 10 })}>
    Hooray, styles!
  </div>
</div>

Styled

In addition to css you can also use styled to create an element and style it.

Similar to css, styled can be used with a string, a tagged template literal, an object of an array.

When you use styled to create an element you can then create new elements with properties that can then be utilized in your styles. This opens the door for easy customization and reuse:

const Heading = styled("h1")`
  background-color: ${props => props.bg};
  color: ${props => props.fg};
`;

Which creates a Heading component that accepts bg and fg properties that will set the background and text colors:

<Heading bg="#008f68" fg="#fae042">
  Heading with yellow text and a green background!
</Heading>

Taking things a step further, we can take our Heading component and extend it, bringing the background and foreground color properties along with it:

const Subheading = Heading.withComponent("h2");

The properties themselves are not mandatory, so you include / omit them as you see fit:

<Subheading fg="#6db65b">
  Subheading with default colors!
</Subheading>
<Subheading fg="#6db65b">
  Subheading with light green text!
</Subheading>
<Subheading bg="#6db65b">
  Subheading with light green background!
</Subheading>

Just like css, you can specify your styles as an object instead of as a string:

const Quote = styled("blockquote")(props => ({
  fontSize: props.size,
}));

And even include an object of default styles:

const Cite = styled("cite")(
  {
    fontWeight: 100
  },
  props => ({
    fontWeight: props.weight
  })
);

That can be optionally set when using the component:

<Cite>
  Citation with light text!
</Cite>
<Cite weight={700}>
  Citation with heavy text!
</Cite>

As mentioned before, with emotion you can specify !important styles with ease:

const Footer = styled("footer")`
  margin-top: 50px !important;
`;

Putting It All Together

Now that we’ve went through a bunch of disparate use cases, let’s go crazy and put them together into a more cohesive example:

import React from "react";
import { render } from "react-dom";
import styled, { css } from "react-emotion";

const Heading = styled("h1")`
  background-color: ${props => props.bg};
  color: ${props => props.fg};
`;

const Subheading = Heading.withComponent("h2");

const Quote = styled("blockquote")(props => ({
  fontSize: props.size
}));

const Cite = styled("cite")(
  {
    fontWeight: 100
  },
  props => ({
    fontWeight: props.weight
  })
);

const Footer = styled("footer")`
  border-top: 1px solid #ccc;
  color: #ccc;
  margin-top: 50px !important;
  padding-top: 20px;
`;

function App() {
  return (
    <div className={css`background: #ddd;`}>
      <div className={css({ padding: 10 })}>
        <Heading bg="#008f68" fg="#fae042">
          Gator Lyrics
        </Heading>
        <Subheading fg="#6db65b">
          Lyrics from songs that contain the word "alligator"
        </Subheading>
        <Quote size={28}>
          See you later, alligator. After a while, crocodile.
        </Quote>
        <Cite weight={700}>Bill Haley</Cite>
        <Footer>EOF</Footer>
      </div>
    </div>
  );
}

const container = document.createElement("div");
document.body.appendChild(container);
render(<App />, container);

That’s how you can style with emotion in your React app!

To see a live example of the code above, you can check out this CodeSandbox.

Enjoy! 💥

  Tweet It

🕵 Search Results

🔎 Searching...