---
title: 'The css Prop'
---

The primary way to style elements with emotion is the `css` prop. It provides a concise and flexible API to style your components.

## Get Started

There are 2 ways to get started with the `css` prop.

- [Babel Preset](#babel-preset)
- [JSX Pragma](#jsx-pragma)

Both methods result in the same compiled code.
After adding the preset or setting the pragma as a comment, compiled jsx code will use emotion's `jsx` function instead of `React.createElement`.

|        | Input                      | Output                                              |
| ------ | -------------------------- | --------------------------------------------------- |
| Before | `<img src="avatar.png" />` | `React.createElement('img', { src: 'avatar.png' })` |
| After  | `<img src="avatar.png" />` | `jsx('img', { src: 'avatar.png' })`                 |

#### Babel Preset

This method will **not** work with [Create React App](https://github.com/facebook/create-react-app) or other projects that do not allow custom Babel configurations.
Use the [JSX Pragma](#jsx-pragma) method instead.

**.babelrc**

```json
{
  "presets": ["@emotion/babel-preset-css-prop"]
}
```

> [Full `@emotion/babel-preset-css-prop` documentation](https://emotion.sh/docs/@emotion/babel-preset-css-prop)

If you are using the compatible React version (`>=16.14.0`) then you can opt into using [the new JSX runtimes](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) by using such configuration:

**.babelrc**

```json
{
  "presets": [
    [
      "@babel/preset-react",
      { "runtime": "automatic", "importSource": "@emotion/react" }
    ]
  ],
  "plugins": ["@emotion/babel-plugin"]
}
```

In case you want to use the new JSX runtimes with [Next.js](https://nextjs.org/) and you are using their [`next/babel`](https://nextjs.org/docs/advanced-features/customizing-babel-config) preset then the configuration should look like this:

**.babelrc**

```json
{
  "presets": [
    [
      "next/babel",
      {
        "preset-react": {
          "runtime": "automatic",
          "importSource": "@emotion/react"
        }
      }
    ]
  ],
  "plugins": ["@emotion/babel-plugin"]
}
```

#### JSX Pragma

Set the jsx pragma at the top of your source file that uses the `css` prop.
This option works best for testing out the `css` prop feature or in projects where the babel configuration is not configurable (create-react-app, codesandbox, etc.).

```js
/** @jsx jsx */
```

Similar to a comment containing linter configuration, this configures the [jsx babel plugin](https://babeljs.io/docs/en/babel-plugin-transform-react-jsx) to use the `jsx` function instead of `React.createElement`.

If you are using a zero-config tool with automatic detection of which runtime (classic vs. automatic) should be used and you are already using a React version that has [the new JSX runtimes](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) (hence `runtime: 'automatic'` being configured automatically for you) such as Create React App 4 then `/** @jsx jsx */` pragma might not work and you should use `/** @jsxImportSource @emotion/react */` instead.

> [JSX Pragma Babel Documentation](https://babeljs.io/docs/en/babel-plugin-transform-react-jsx#pragma)

#### Import the `jsx` function from `@emotion/react`

```js
/** @jsx jsx */
import { jsx } from '@emotion/react'
```

Note that excluding this will cause your css to render as `[Object Object]`.

#### Use the `css` prop

Any component or element that accepts a `className` prop can also use the `css` prop. The styles supplied to the `css` prop are evaluated and the computed class name is applied to the `className` prop.

## Object Styles

The `css` prop accepts object styles directly and does not require an additional import.

```jsx
// @live
render(
  <div
    css={{
      backgroundColor: 'hotpink',
      '&:hover': {
        color: 'lightgreen'
      }
    }}
  >
    This has a hotpink background.
  </div>
)
```

> [Object Style Documentation](/docs/object-styles.mdx).

## String Styles

To pass string styles, you must use `css` which is exported by `@emotion/react`, it can be used as a [tagged template literal](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) like below.

```jsx
// @live
import { css } from '@emotion/react'

const color = 'darkgreen'

render(
  <div
    css={css`
      background-color: hotpink;
      &:hover {
        color: ${color};
      }
    `}
  >
    This has a hotpink background.
  </div>
)
```

> Note:
>
> **`css` from `@emotion/react` does not return the computed class name string.** The function returns an object containing the computed name and flattened styles. The returned object is understood by emotion at a low level and can be composed with other emotion based styles inside of the `css` prop, other `css` calls, or the `styled` API.

You can also pass in your css as variables, which allows for composition (read more about this [here](https://emotion.sh/docs/composition)).

## Style Precedence

- Class names containing emotion styles from the `className` prop override `css` prop styles.
- Class names from sources other than emotion are ignored and appended to the computed emotion class name.

The precedence order may seem counter-intuitive, but it allows components with styles defined on the `css` prop to be customized via the `className` prop passed from the parent.

The `P` component in this example has its default styles overridden in the `ArticleText` component.

```jsx
const P = props => (
  <p
    css={{
      margin: 0,
      fontSize: 12,
      lineHeight: '1.5',
      fontFamily: 'Sans-Serif',
      color: 'black'
    }}
    {...props} // <- props contains the `className` prop
  />
)

const ArticleText = props => (
  <P
    css={{
      fontSize: 14,
      fontFamily: 'Georgia, serif',
      color: 'darkgray'
    }}
    {...props} // <- props contains the `className` prop
  />
)
```

The `ArticleText` component can be customized and the styles composed with its default styles. The result is passed `P` and the process repeats.

```jsx
const P = props => (
  <p
    css={{
      margin: 0,
      fontSize: 12,
      lineHeight: '1.5',
      fontFamily: 'sans-serif',
      color: 'black'
    }}
    {...props} // <- props contains the `className` prop
  />
)

const ArticleText = props => (
  <P
    css={{
      fontSize: 14,
      fontFamily: 'Georgia, serif',
      color: 'darkgray'
    }}
    {...props} // <- props contains the `className` prop
  />
)

const SmallArticleText = props => (
  <ArticleText
    css={{
      fontSize: 10
    }}
    {...props} // <- props contains the `className` prop
  />
)
```

The styles are concatenated together and inserted via `insertRule`.

1. `P` component

```css
.css-1 {
  margin: 0;
  font-size: 12px;
  line-height: 1.5;
  font-family: sans-serif;
  color: black;
}
```

2. `ArticleText` component

```css
.css-2 {
  font-size: 14px;
  font-family: Georgia, serif;
  color: darkgray;
}
```

3. `SmallArticleText` component

```css
.css-3 {
  font-size: 10px;
}
```

4. Result

```diff
.css-result {
+ margin: 0;
- font-size: 12px;
+ line-height: 1.5;
- font-family: 'sans-serif';
- color: black;
- font-size: 14px;
+ font-family: Georgia, serif;
+ color: darkgray;
+ font-size: 10px;
}
```

Relying on the css spec's ["Order of Appearance"](https://www.w3.org/TR/css-cascade-3/#cascade-order) rule, property values defined later (green) override those before it (red).

## Gotchas

- If you include the plugin `@babel/plugin-transform-react-inline-elements` in your `.babelrc` your styles will not be applied. The plugin is not compatible with the `css` prop.
- When using `React.cloneElement` you can't easily add a css prop if the cloned element doesn't already have it. Otherwise `React.cloneElement` works with `jsx`-created elements.
