--- 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 | `` | `React.createElement('img', { src: 'avatar.png' })` | | After | `` | `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(
This has a hotpink background.
) ``` > [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(
This has a hotpink background.
) ``` > 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 => (

) const ArticleText = props => (

) ``` 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 => (

) const ArticleText = props => (

) const SmallArticleText = props => ( ) ``` 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.