---
title: Merging Styles
description: Learn how to merge multiple styles without conflicts.
---

## Merging `css` objects

You can merge multiple style objects together using the `css` function.

```js
import { css } from 'styled-system/css'

const style1 = {
  bg: 'red',
  color: 'white',
}

const style2 = {
  bg: 'blue',
}

const className = css(style1, style2) // => 'bg_blue c_white'
```

In some cases though, the style object might not be colocated in the same file as the component. In this case, you can
use the `css.raw` function to preserve the original style object.

> `css.raw(...)` and a config recipe's `.raw(...)` are identity functions: they return their input, and serve as a hint
> to the compiler that the value is a style object. `cva(...).raw(...)` and `sva(...).raw(...)` are not — they resolve
> the variants and return the merged style object, which is what makes the `cva` example below work.

```js
// style.js
import { css } from 'styled-system/css'

export const style1 = css.raw({
  bg: 'red',
  color: 'white',
})

// component.js
import { css } from 'styled-system/css'
import { style1 } from './style.js'

const style2 = css.raw({
  bg: 'blue',
})

const className = css(style1, style2) // => 'bg_blue c_white'
```

## Spreading `css.raw` objects

> **Added in v1.6.1**

You can also spread `css.raw` objects within style declarations. This is particularly useful for reusing styles in
nested selectors, conditions, and complex compositions:

### Child selectors

```js
import { css } from 'styled-system/css'

const baseStyles = css.raw({ margin: 0, padding: 0 })

const component = css({
  '& p': { ...baseStyles, fontSize: '1rem' },
  '& h1': { ...baseStyles, fontSize: '2rem' },
})
```

### Nested conditions

```js
import { css } from 'styled-system/css'

const interactive = css.raw({ cursor: 'pointer', transition: 'all 0.2s' })

const card = css({
  _hover: {
    ...interactive,
    _dark: { ...interactive, color: 'white' },
  },
})
```

## Merging `cva` + `css` styles

The same technique can be used to merge an inline `cva` recipe and a style object.

```js
import { css, cx, cva } from 'styled-system/css'

const overrideStyles = css.raw({
  bg: 'red',
  color: 'white',
})

const buttonStyles = cva({
  base: {
    bg: 'blue',
    border: '1px solid black',
  },
  variants: {
    size: {
      small: { fontSize: '12px' },
    },
  },
})

const className = css(
  // returns the resolved style object
  buttonStyles.raw({ size: 'small' }),
  // add the override styles
  overrideStyles,
)

// => 'bg_red bd_1px_solid_black c_white fs_12px'
```

## Merging `sva` + `css` styles

The same technique can be used to merge an inline `sva` recipe and a style object.

```js
import { css, sva } from 'styled-system/css'

const overrideStyles = css.raw({
  bg: 'red',
  color: 'white',
})

const buttonStyles = sva({
  slots: ['root'],
  base: {
    root: {
      bg: 'blue',
      border: '1px solid black',
    },
  },
  variants: {
    size: {
      small: {
        root: { fontSize: '12px' },
      },
    },
  },
})

// returns the resolved style object for all slots
const { root } = buttonStyles.raw({ size: 'small' })

const className = css(
  root,
  // add the override styles
  overrideStyles,
)

// => 'bg_red bd_1px_solid_black c_white fs_12px'
```

## Merging config recipe and style object

With the Vite compiler, an analyzable `cx()` composes the recipe and utility StyleSets before allocating shared atoms.
Later arguments win, and losing declarations are not emitted for that composition.

```js
import { css, cx } from 'styled-system/css'
import { button } from 'styled-system/recipes'

const className = cx(
  // resolves the selected recipe declarations
  button({ size: 'small' }),
  // add the override styles
  css({ bg: 'red' }), // => 'bg_red'
)

// => a shared atom string containing the final red background
```

That override works because Vite can see and compose both Bamboo StyleSets. If one argument is an arbitrary runtime
class, `cx` remains a string join and makes no conflict guarantee — see
[Classname concatenation](/docs/concepts/writing-styles#classname-concatenation).

## Merging within JSX component

Using these techniques, you can apply them to a component by exposing a `css` prop and merge with local styles.

```jsx
const cardStyles = css.raw({
  bg: 'red',
  color: 'white',
})

function Card({ title, description, css: cssProp }) {
  return (
    // merge the `cardStyles` with the `cssProp` passed in
    <div className={css(cardStyles, cssProp)}>
      <h1>{title}</h1>
      <p>{description}</p>
    </div>
  )
}

// usage
function Demo() {
  return <Card title="Hello World" description="This is a card component" css={{ bg: 'blue' }} />
}
```

Any prop name other than `css` works the same way, except the caller must wrap the object in `css.raw(...)` for Bamboo
to extract it:

```jsx
function Card({ title, description, style }) {
  return <div className={css(cardStyles, style)}>{/* ... */}</div>
}

// usage
;<Card title="Hello World" description="This is a card component" style={css.raw({ bg: 'blue' })} />
```
