React allows you to style components directly with the style
property. For most situations, using the style
prop to pass an object of CSS properties is sufficient.
However, for situations that require more demanding styling features, emotion
can provide a solution. emotion
is a flexible and highly performant CSS-in-JS library. It accepts strings and objects, supports defaulting and extending variables, and with an additional Babel plugin even supports inline child selectors.
In this article, you will build a React application that uses the @emotion/react
and @emotion/styled
packages for styling.
To complete this tutorial, you’ll need:
Note: This article previously recommended the emotion
and react-emotion
packages. Now several versions later, @emotion/react
and @emotion/styled
are the modern approach.
This tutorial was verified with Node v15.3.0, npm
v7.4.0, react
v17.0.1, @emotion/react
v11.1.4, and @emotion/styled
v11.0.0.
Start with using create-react-app
to generate a React App and then install dependecies:
- npx create-react-app react-emotion-example
Change into the new project directory:
- cd react-emotion-example
Next, install @emotion/react
and @emotion/styled
via npm
:
- npm install @emotion-react@11.1.4 @emotion/styled@11.0.0
At this point, you will have a new React project with @emotion/react
.
css
Propemotion
provides a css
prop that can accept nested selectors and media queries. It can support an object or a tagged template literal.
Open the App.js
file in your code editor and modify it to use <div>
s with the css
prop:
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
function App() {
return (
<div>
<div css={css({
margin: 10,
padding: 10,
backgroundColor: '#eee',
})}>
This is an example of <code>`css`</code> using an object.
</div>
<div css={css`
margin: 10px;
padding: 10px;
background-color: #eee;
`}>
This is an example of <code>`css`</code> using a tagged template literal.
</div>
</div>
);
}
export default App;
The first example uses an object with style object properties and values. The second example uses a tagged template literal with CSS rules.
Note: Since this tutorial is relying upon Create React App 4, it is necessary to specify /** @jsxImportSource @emotion/react */
. This comment informs Babel to customize the automatic runtime import.
Run the application:
- npm start
Observe the application in your browser. This will produce two identical <div>
s with ten pixels of margin
, ten pixels of padding
, and grey background color.
styled
Componentsemotion
also supports a styled
component to create an element and style it. It can also support an object or a tagged template literal.
Let’s consider a Heading
component that generates a h1
heading element and accepts bg
(background) and fg
(foreground) properties that will set the background-color
and color
:
const Heading = styled('h1')`
background-color: ${props => props.bg};
color: ${props => props.fg};
`;
When using this Heading
component, you will be able to pass color values to bg
and fg
:
<Heading bg="#008f68" fg="#fae042">
Heading with a green background and yellow text.
</Heading>
Revisit App.js
in your code editor and modify it to use styled
components:
import styled from '@emotion/styled';
const Heading = styled('h1')`
background-color: ${props => props.bg};
color: ${props => props.fg};
`;
function App() {
return (
<div>
<Heading bg="#008f68" fg="#fae042">
Heading with a green background and yellow text.
</Heading>
</div>
);
}
export default App;
This code will result in an h1
element with a green background and yellow text.
Next, consider a Subheading
component that extends the Heading
component and changes the rendered text using withComponent
:
const Subheading = Heading.withComponent('h2');
Instead of a h1
heading, the component will render with a h2
heading.
This code will produce an h2
with default colors:
<Subheading>
Subheading with default colors.
</Subheading>
This code will produce an h2
with light green text:
<Subheading fg="#6db65b">
Subheading with light green text.
</Subheading>
This code will produce an h2
with a light green background:
<Subheading bg="#6db65b">
Subheading with light green background.
</Subheading>
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.
This code uses the default fontWeight
value:
<Cite>
Citation with light text!
</Cite>
This code provides a weight
prop which overrides the default fontWeight
value:
<Cite weight={700}>
Citation with heavy text!
</Cite>
With emotion
you can specify !important
styles:
const Footer = styled('footer')`
margin-top: 50px !important;
`;
This code produces a footer
element with a margin-top
of 50 pixels.
css
Props and styled
ComponentsNow, reflect on what you have learned in the previous examples and use those concepts to construct a component that uses css
props and styled
components.
Revisit App.js
with your code editor and replace the content with
the following lines of code:
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
import styled from '@emotion/styled';
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 css={css`background: #ddd;`}>
<div css={css({ padding: 10 })}>
<Heading bg="#008f68" fg="#fae042">
Quotations
</Heading>
<Subheading fg="#6db65b">
For React Developers
</Subheading>
<Quote size={28}>
I built this with <code>`emotion/react`</code> and <code>`emotion/styled`</code>!
</Quote>
<Cite weight={700}>Sammy</Cite>
<Footer>Shark Facts</Footer>
</div>
</div>
);
}
export default App;
This code utilizes css
props and styled
components with strings and objects. It also utilizes extending styled
components using withComponent
and overriding styled
components with default values.
In this article, you built a React application that uses the @emotion/react
and @emotion/styled
packages for styling.
If you’d like to learn more about React, take a look at our How To Code in React.js series, or check out our React topic page for exercises and programming projects.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Great article! I’m mainly learning about emotion so I can use github.com/arwes. This has helped a lot!