---
url: https://unocss.dev/config/variants.md
description: Variants allow you to apply some variations to your existing rules.
---

# Variants

[Variants](https://windicss.org/utilities/general/variants.html) allow you to apply some variations to your existing rules, like the `hover:` variant from Tailwind CSS.

## Example

```ts
variants: [
  // hover:
  (matcher) => {
    if (!matcher.startsWith('hover:'))
      return matcher
    return {
      // slice `hover:` prefix and passed to the next variants and rules
      matcher: matcher.slice(6),
      selector: s => `${s}:hover`,
    }
  },
],
rules: [
  [/^m-(\d)$/, ([, d]) => ({ margin: `${d / 4}rem` })],
]
```

* `matcher` controls when the variant is enabled. If the return value is a string, it will be used as the selector for matching the rules.
* `selector` provides the availability of customizing the generated CSS selector.

## Under the hood

Let's have a tour of what happened when matching for `hover:m-2`:

* `hover:m-2` is extracted from users usages
* `hover:m-2` send to all variants for matching
* `hover:m-2` is matched by our variant and returns `m-2`
* the result `m-2` will be used for the next round of variants matching
* if no other variant is matched, `m-2` will then goes to match the rules
* our first rule get matched and generates `.m-2 { margin: 0.5rem; }`
* finally, we apply our variants' transformation to the generated CSS. In this case, we prepended `:hover` to the `selector` hook

As a result, the following CSS will be generated:

```css
.hover\:m-2:hover { margin: 0.5rem; }
```

With this, we could have `m-2` applied only when users hover over the element.

## Going further

The variant system is very powerful and can't be covered fully in this guide, you can check [the default preset's implementation](https://github.com/unocss/unocss/tree/main/packages-presets/preset-mini/src/_variants) to see more advanced usages.
