# Class Merge

Resolve two utilities that set the same property so the last one wins.

## The Problem

When two utilities set the same property, the one later **in the stylesheet** wins, whatever their order in `class`.

```tsx "c:white" "c:accent"
<span className="c:white c:accent">Accent</span>
<span className="c:accent c:white">Accent</span>
```

Both render white, because `c:white` is generated after `c:accent`. So passing `c:accent` to a component that already sets `c:white` does nothing.

## Using Merge

`merge` takes class strings & returns one with the losers removed, so the last class wins.

```tsx
import { merge } from "yummacss/merge";

merge("c:white", "c:accent"); // "c:accent"
```

It ships with the `yummacss` package, so there is nothing extra to install.

```tsx
<span className={merge("c:white", className)}>Accent</span>
```

Falsy arguments are skipped, so conditionals read cleanly.

```tsx
<div className={merge("d:f ai:c", isOpen && "bg:silver-1", className)}></div>
```

## What Gets Dropped

A class is dropped only when a later class sets **everything** it sets.

```tsx
merge("px:8 p:4"); // "p:4"
merge("p:4 px:8"); // "p:4 px:8"
```

`p:4` covers `px:8`, so `px:8` goes. Reversed, both stay, since `p:4` still sets the block axis.

```tsx
merge("w:10 h:10", "w:12"); // "h:10 w:12"
```

## Shared Prefixes

`merge` reads the value, so a shared prefix never collides: `c:p` is a cursor, `c:slate-10` a color.

```tsx
merge("c:p c:slate-10"); // "c:p c:slate-10"
merge("p:a p:4"); // "p:a p:4"
```

## Variants

Classes are compared within their own variant, so a hover class never covers a base class.

```tsx
merge("h:bg:silver-2", "bg:white"); // "h:bg:silver-2 bg:white"
merge("h:bg:silver-2", "h:bg:indigo-2"); // "h:bg:indigo-2"
```

Media queries work the same way.

```tsx
merge("@lg:p:4 p:2", "@lg:p:8"); // "p:2 @lg:p:8"
```

## Unknown Classes

Anything `merge` does not recognize passes through in place.

```tsx
merge("card", "bg:white", "card-active"); // "card bg:white card-active"
```

> **Note**
>
> A utility newer than your `merge` is kept too, so the worst case is the
> behavior you had before.

## Alternatives

- **`@layer`** ranks a class everywhere it is used, so demoting `c:white` would demote it on every element, not only the one you override.
- **`!important`** wins everywhere the class appears, and does nothing when both classes carry it.

`merge` removes the losing class instead, so only what you meant reaches the DOM.