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.
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.
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.
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.
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.
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.
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.
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.
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> )
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> )
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> )
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.
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ 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>
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowBuild scalable admin dashboards with Filament and Laravel using Form Builder, Notifications, and Actions for clean, interactive panels.
Break down the parts of a URL and explore APIs for working with them in JavaScript, parsing them, building query strings, checking their validity, etc.
In this guide, explore lazy loading and error loading as two techniques for fetching data in React apps.
Deno is a popular JavaScript runtime, and it recently launched version 2.0 with several new features, bug fixes, and improvements […]
4 Replies to "Styled-components vs. Emotion for handling CSS"
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.
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.
The styled-components examples have the wrong imports in the code blocks. You should correct these for clarity.
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.