Emotion is a popular library for writing CSS-in-JS in React and other JavaScript applications. It allows developers to style their components using JavaScript instead of traditional CSS files. Emotion provides powerful and flexible tools for styling, with both styled components and CSS prop options, offering a rich developer experience for building modern, scalable web applications.
1. What is Emotion?
Emotion is a library that helps you write styles in JavaScript. It allows you to define styles within your components, manage them dynamically, and scope them to individual components, all while keeping the full power of CSS. Emotion provides two main ways of styling:
- Styled Components: Create styled components using tagged template literals.
- CSS Prop: Use the
css
prop to apply styles directly to components.
2. Why Use Emotion for Styling in React?
Emotion offers a variety of benefits, such as:
- Dynamic Styling: Easily use props, theme values, or state to dynamically change the styles of components.
- Scoped Styles: The styles are automatically scoped to the components, preventing style leakage or conflicts.
- Performance: Emotion is highly optimized for performance and does not incur unnecessary runtime overhead.
- Integration with JavaScript: You can use the full power of JavaScript to write your styles, such as conditionally applying styles or using JavaScript variables inside styles.
- Theming Support: Emotion supports theme management, enabling you to define a central theme and use it consistently across components.
3. Setting Up Emotion in a React Project
To use Emotion in a React project, you can install it via npm or yarn:
- Install Emotion:
npm install @emotion/react @emotion/styled
- Using Emotion in React:
Once Emotion is installed, you can start using it in your components by importing either the styled
function or the css
prop.
4. Using the styled
API in Emotion
The styled
API in Emotion allows you to create styled components using template literals, similar to Styled Components.
Example 1: Styled Components with Emotion
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
import styled from '@emotion/styled';
const Button = styled.button`
background-color: #007bff;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
&:hover {
background-color: #0056b3;
}
`;
function App() {
return (
<div>
<Button>Click Me</Button>
</div>
);
}
export default App;
In this example, the Button
component is created using the styled.button
function, and it will have styles scoped to it. You can define all CSS properties as usual, and Emotion will handle injecting the styles into the DOM.
5. Using the css
Prop in Emotion
Emotion also supports the css
prop, which allows you to apply styles directly to a component or an element using JavaScript objects or template literals.
Example 2: Using the css
Prop in Emotion
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
function App() {
return (
<div>
<button
css={css`
background-color: #28a745;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
&:hover {
background-color: #218838;
}
`}
>
Click Me
</button>
</div>
);
}
export default App;
Here, we use the css
prop to apply the styles to a button directly. This is a more inline and dynamic way of styling components, which can be useful when the styles depend on JavaScript variables or conditions.
6. Dynamic Styling with Emotion
Emotion excels at dynamic styling. You can pass props, states, or themes to influence the styles. Here’s an example of dynamic styling based on props:
Example 3: Dynamic Styling with Emotion
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
function Button({ primary, children }) {
return (
<button
css={css`
background-color: ${primary ? '#007bff' : '#6c757d'};
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
&:hover {
background-color: ${primary ? '#0056b3' : '#5a6268'};
}
`}
>
{children}
</button>
);
}
function App() {
return (
<div>
<Button primary>Primary Button</Button>
<Button>Secondary Button</Button>
</div>
);
}
export default App;
In this example, the Button
component changes its background color based on the primary
prop. Emotion allows you to easily incorporate JavaScript expressions to make your styles dynamic.
7. Theming in Emotion
Emotion provides built-in support for theming. You can define a theme and apply it globally across your application.
Example 4: Setting Up and Using Themes in Emotion
- Define a Theme:
// theme.js
const theme = {
colors: {
primary: '#007bff',
secondary: '#6c757d',
},
spacing: {
small: '8px',
medium: '16px',
},
};
export default theme;
- Apply Theme Using
ThemeProvider
:
/** @jsxImportSource @emotion/react */
import { ThemeProvider } from '@emotion/react';
import theme from './theme';
import { css } from '@emotion/react';
function App() {
return (
<ThemeProvider theme={theme}>
<div
css={css`
background-color: ${props => props.theme.colors.primary};
padding: ${props => props.theme.spacing.medium};
color: white;
`}
>
Themed Button
</div>
</ThemeProvider>
);
}
export default App;
In this example, the ThemeProvider
component makes the theme available to all components, and the styles are applied dynamically based on the theme values.
8. Advantages of Using Emotion
- Flexible: Emotion allows for both styled components and the
css
prop, giving developers flexibility in how they approach styling. - Dynamic: Supports dynamic styles based on JavaScript variables, props, state, and themes.
- CSS-in-JS: Allows for writing CSS directly in JavaScript, enabling scoped, modular, and reusable styles.
- Optimized Performance: Emotion is highly performant, handling styles efficiently and minimizing the number of styles injected into the DOM.
- Support for Themes: Emotion has built-in theming support, making it easier to manage and customize design across a large application.