React CSS in JS: emotion vs styled components
CSS has been giving styles to web pages for years and more and more features are continuously being added to CSS and you can’t find any web page without CSS nowadays.
There are different ways to add css to react applications including global styles and inline styles which are not recommended. one of the best ways to add styles to your components is css in js which will allow you to use javascript variables in css, isolate component styles and make styles more dynamic and reusable.
While some other SPA frameworks have in-component css solutions natively (like the beloved Vue js) react just doesn’t . so even though we could use solutions like creating a css file for each component or using css modules (which a lot of devs do) there are third party libraries that can make us able to add css to component js or tsx files which is more efficient and convenient.
Two of the most popular css in js libraries are emotion and styled components, so let’s compare them and find out which one is better to use.
Styled Components
styled components allows you to create styled reusable react components and most importantly restyle existing components which is very useful when you want to customize imported components or wrap and customize components from ui libraries.
usage:
import styled from 'styled-components'
const App = () => {
const color = 'blue';
return (
<BlueDiv color={color}>
Hello World
</BlueDiv>
);
}
const BlueDiv = styled.div`
background-color: ${props => props.color};
`;
export default App;
styled components supports nested styling, media queries, theming and keyframes which makes it a powerful library for styling. in the above example you can see that we can also pass props to a styled component and you can use js in them, after all this is the best advantage of css in js!
Emotion
emotion is one of the most popular css in js libraries, it allows you to pass styles to elements “className” props like so:
import { css, cx } from '@emotion/css'
const App = () => {
const color = 'blue'
const styles = css`
background-color: ${color};
`;
return (
<div className={styles}>
Hello World
</div>
);
}
export default App;
This is the framework agnostic way which is more lightweight and it doesn’t require external plugins or additional setup. by doing this a class name with the passed styles will be generated for the div.
Emotion also has a react module which adds a new “css” prop which is more efficient than the framework agnostic method and it supports nested selectors and media queries:
import { css, jsx } from '@emotion/react'
const App = () => {
const styles = css`
color: turquoise;
@media (min-width: 420px) {
font-size: 50px;
}
a {
border-bottom: 1px solid currentColor;
cursor: pointer;
}
`;
return (
<p css={styles}>
Hello World
<a>nested element</a>
</p>
)
}
export default App;
emotion react also supports SSR and theming and it is predictable and easy to test.
another interesting feature of emotion is it has a “styled api” which has a similar syntax to styled-components.
Comparison
both libraries are useful and popular they both support necessary features for styling. however, despite the fact that styled components has more github stars and contributes and I have used it more than emotion, emotion is newer, has a smaller bundle size and it’s performance is reportedly better and it has more features than styled components, thanks to it’s “styled api” you can create styled components just like “styled components”! so I think emotion is the library to go with.