Styled-components vs. Emotion for handling CSS

4 min read 1139

Introduction

As JavaScript has gone through many moderations and improvements in the last few years, we have seen several new libraries for handling CSS inside JavaScript code. styled-components and Emotion are two main CSS-in-JS libraries that developers mostly use while styling components in popular JavaScript frameworks such as React.

In this article, we will compare styled-components and Emotion, including differences, drawbacks, and benefits.

Overview

Styledcomponents

The styled-components library allows developers to create new styled react components and restyle existing react components. Props are major functioning elements of styled-components, especially for changes in object styling.

In my opinion, the biggest advantage of styled-components is that you can style any component using this particular library as long as it accepts a className prop. You can also use the withComponent function helper to change the rendered tag that is attached to a specific component. This may be needed if you want to reuse certain styles from a particular component in a different component later. In such a case, you would have to change the rendered tag to perform the operation.

Emotion

The uses for Emotion are very different from those of styled-components. The main feature of this library is that the style composition is predictable for writing different CSS styles using JavaScript. This library supports both string and object styles.

Generally speaking, there are two main methods for using Emotion: framework-agnostic and with React. There are benefits and drawbacks to each, as we will discuss below.

Framework-agnostic

Unlike other types of styling methods, the framework-agnostic approach does not require external plugins or additional setup. Emotion comes with a reliable support system — regardless of framework — that is proficient in handling auto vendor-prefixing, nested selectors, and other functions.

Moreover, with the framework-agnostic approach, it is easy to generate different class names because you can use the simplest CSS functions to do so.

React method

Using the React method with Emotion is the best approach for creating unique and unconventional inline design work, and functions best when applied in a configurable build environment. When you’re using this method, you get dedicated CSS prop support that ensures enhanced styling options, as well as server-side rendering with zero configuration.

Comparing styled-components to Emotion

When it comes to writing CSS for JavaScript, both styled-components and Emotion are highly efficient, perform well, and have a dedicated developer base that use each library for specific purposes.

In the following sections, we will look at the different reasons to use each library to help you decide which is right for you.

Why would you choose styled-components?

Styled-components are moderated versions of React components, which makes it fairly easy to pass props to styled-components. This feature makes the process of writing CSS using styled-components a lot easier. You can also restyle and retheme existing regular components through styled-components.

For performing theming tasks, styled-components are a great option that support many looks, themes, and feels for customization. Styled-components also allow for global styling that is applicable for all types of styled-components. When you create a global style that is applicable for all components, you can save time and effort when handling different styled-components at the same time.

In additional to the features listed above, styled-components are easily switched from one HTML component to other HTML components. This flexibility makes this library a better option than other methods in terms of CSS writing. For instance, once certain HTML elements are rendered by styled-components, the developer is then able to add extra attributes to those HTML elements.

Finally, styled-components are compatible with nearly all CSS frameworks to help you with all of your theming and styling needs.



Why use Emotion for writing CSS?

In general, Emotion is more developer-friendly than other libraries. The biggest advantage of Emotion is its easily handled object styles for writing CSS.

Take, for example, the case of styled-components, wherein the developer must create unique names for different components, all while avoiding identical naming styles. If you fail to follow distinct styles or you name a component without a meaningful descriptor, all your efforts can be wasted in seconds. On the other hand, the naming tasks are quite simple in Emotion, as they rely on the application of CSS props.

Finally, many developers prefer Emotion to other CSS-in-JS alternatives because of its small size, high performance, and overall flexibility.

Different styling options with styled-components and Emotion

Styling using styled-components

We will begin by looking at some sample code for styling components:

import styled from '@emotion/styled'

const Button = styled.button`
  color: turquoise;
`

render(<Button>This my button component.</Button>)

Note that you can make changes to the styles of the components, or create new styles, with the implementation of props:

import styled from '@emotion/styled'

const Button = styled.button`
  color: ${props =>
    props.primary ? 'hotpink' : 'turquoise'};
`

const Container = styled.div(props => ({
  display: 'flex',
  flexDirection: props.column && 'column'
}))

render(
  <Container column>
    <Button>This is a regular button.</Button>
    <Button primary>This is a primary button.</Button>
  </Container>
)

In the example below, we can use the className prop to create styles:

import styled from '@emotion/styled'
const Basic = ({ className }) => (
  <div className={className}>Some text</div>
)

const Fancy = styled(Basic)`
  color: hotpink;
`

render(<Fancy />)

Finally, we can change the render tag in styled-components. In the following code block, notice how the second component has the same styles as Section, but renders as an aside:

import styled from '@emotion/styled'

const Section = styled.section`
  background: #333;
  color: #fff;
`
const Aside = Section.withComponent('aside')
render(
  <div>
    <Section>This is a section</Section>
    <Aside>This is an aside</Aside>
  </div>
)

Using Emotion for framework-agnostic styling

Since Emotion is streamlined for styling components, the framework-agnostic method is pretty simple:

import { css, cx } from '@emotion/css'

const color = 'white'

render(
  <div
    className={css`
      padding: 32px;
      background-color: hotpink;
      font-size: 24px;
      border-radius: 4px;
      &:hover {
        color: ${color};
      }
    `}
  >
    Hover to change color.
  </div>
)

Using Emotion to style components in React

The approach is similarly straightforward in React:

// this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement
/** @jsx jsx */
import { css, jsx } from '@emotion/react'

const color = 'white'

render(
  <div
    css={css`
      padding: 32px;
      background-color: hotpink;
      font-size: 24px;
      border-radius: 4px;
      &:hover {
        color: ${color};
      }
    `}
  >
    Hover to change color.
  </div>
)

Conclusion

For simple, efficient, and uncomplicated styling, Emotion is a great CSS-to-JS library. On the other hand, for more unique and complex styling options, styled-components may be the better way to go. As is often the case with writing CSS, much of the decision-making process comes down to project setup and personal preference.

Get set up with LogRocket's modern React error tracking in minutes:

  1. Visit https://logrocket.com/signup/ to get an app ID.
  2. Install LogRocket via NPM or script tag. LogRocket.init() must be called client-side, not server-side.
  3. $ npm i --save logrocket 

    // Code:

    import LogRocket from 'logrocket';
    LogRocket.init('app/id');
    Add to your HTML:

    <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
    <script>window.LogRocket && window.LogRocket.init('app/id');</script>
  4. (Optional) Install plugins for deeper integrations with your stack:
    • Redux middleware
    • ngrx middleware
    • Vuex plugin
Get started now

4 Replies to “Styled-components vs. Emotion for handling CSS”

  1. Interesting read 🙂

    I did the same comparison a month ago. I built two simple blog applications with a dark theme. One with Emotion and one with Styled Components. I used the object syntax for styling my React components

    Styled components and Emotion looked equal in any way. All I had to do was change the imports.

    Regarding performance and bundle size; there was barely any noticeable difference. The Emotion.js proof of concept was like 2kb smaller.

    Since I was already using Emotion.js for my React projects I chose to stick with it.

  2. Your styled-component examples import from ‘@emotion/styled’ which is misleading, but also highlights the fact that the API for these 2 libraries is nearly identical. It would have been helpful to have a technical breakdown comparing performance, bundle sizes, and limitations of each library.

  3. The styled-components examples have the wrong imports in the code blocks. You should correct these for clarity.

  4. Thanks Kasra for comparing them and thanks Peter for sharing your results too.

    Based on that, I would choose Styled Components because of the community, at least on GitHub, the numbers are double compared to Emotion.

Leave a Reply