---
title: "Custom styles in Tailwind CSS: `@apply`, `theme` or custom plugins"
pubDate: 2022-09-11
permalink: "archive/2022/09/11/custom-styles-tailwind-css-apply-theme-custom-plugins"
tags: ["tailwind-css"]
---

There are three ways to add custom styles to a Tailwind CSS project. As there have been [some recent tweets](https://twitter.com/adamwathan/status/1559250403547652097) around one of them - the `@apply` directive - I'd like to look at and give examples for each.

## What is `@apply`?

`@apply` is a PostCSS directive, provided by Tailwind, to allow re-using it's classes - either when extracting components or overriding third-party styles.

The CSS file is the same as if you were writing traditional CSS, but rather than adding declarations to a ruleset, you use the `@apply` directive and specify the Tailwind CSS class names that you want to apply.

For example:

```css
fieldset {
  @apply bg-primary-dark;
}
```

This is a simple example but it's easy to see how this could be used in ways that weren't intended and how edge-cases can be found.

Adam said in a another tweet:

> I estimate that we spend at least $10,000/month trying to debug extremely edge-case issues people run into by using `@apply` in weird ways.

## Using the `theme` function

As well as `@apply`, Tailwind also provides a `theme` function that you can use in your CSS file. This removes the abstraction of using the class names and adds the ability to retrieve values from the `theme` section of your tailwind.config.js file.

```css
fieldset {
  backgroundColor: theme('colors.primary.dark');
}
```

This seems to be the preferred approach over using `@apply`.

## Creating a custom plugin

The `theme` function is also available if you write a custom Tailwind CSS plugin:

```javascript
const plugin = require('tailwindcss/plugin')

plugin(({ addBase, theme }) => {
  addBase({
    fieldset: {
      backgroundColor: theme('colors.primary.dark'),
    }
  })
})
```

This is an approach that I've used for [generic, open-source plugins](https://github.com/opdavies?tab=repositories&q=%23tailwindcss-plugin) but for project-specific styling, I've mostly used `@apply` or the `theme` function.

That said, I like the modular architecture of having different custom plugins - especially if they're separated into their own files - and being able to easily toggle plugins by simply adding to or removing from the `plugins` array.

I usually don't write many custom styles in a Tailwind project but I think that I'll focus on using the `theme` function going forward, either in a stylesheet or a custom plugin.