---
sidebar_position: 2
---

# Using Tailwind CSS

[Tailwind CSS](https://tailwindcss.com/) is a CSS framework and design system based on Utility Class, which can quickly add common styles to components, and support flexible extension of theme styles.

Modern.js Module supports developing component styles using Tailwind CSS.

## Enabling Tailwind CSS

To use [Tailwind CSS](https://tailwindcss.com/) in Modern.js Module, you can follow the steps below:

1. Run `pnpm run new` in the root directory of your project and make the following selections:

```text
? Please select the operation you want: Enable features
? Please select the feature name: Enable Tailwind CSS
```

After successful initialization, you will see that the `package.json` has added dependencies for `tailwindcss` and `@modern-js/plugin-tailwindcss`.

2. Register the Tailwind plugin in `modern.config.ts`:

```ts title="modern.config.ts"
import { tailwindcssPlugin } from '@modern-js/plugin-tailwindcss';

export default defineConfig({
  plugins: [..., tailwindcssPlugin()],
});
```

3. Create a `index.css` file and add the following code:

```css title="index.css"
/* base and components are optional, please add as appropriate */
@tailwind base;
@tailwind components;
@tailwind utilities;
```

:::info
Depending on your needs, you can selectively import the CSS styles provided by Tailwind CSS. Please refer to the [`@tailwind` documentation](https://tailwindcss.com/docs/functions-and-directives#tailwind) for detailed usage of the `@tailwind` directive.
:::

4. Import the `index.css` file, for example, add the following code in the root component `src/index.jsx`:

```js
import './index.css';
```

5. Now you can use the Utility Classes provided by Tailwind CSS in your components:

```tsx
const Hello = () => (
  <div className="h-12 w-48">
    <p className="text-xl font-medium text-black">hello world</p>
  </div>
);
```

## Configuring Tailwind CSS

In Modern.js Module, you have two ways to configure Tailwind CSS:

1. Using the `tailwind.config.{ts,js}` file, which follows the official usage of Tailwind CSS. Please refer to ["Tailwind CSS - Configuration"](https://tailwindcss.com/docs/configuration) for more details.

```ts title="tailwind.config.ts"
import type { Config } from 'tailwindcss';

export default {
  content: ['./src/**/*.{js,jsx,ts,tsx}'],
} as Config;
```

:::tip
Please upgrade Modern.js to version >= MAJOR_VERSION.33.0 to support automatic reading of `tailwind.config.{ts,js}` files.
:::

2. Using the [style.tailwindcss](/api/config/build-config.html#styletailwindcss) configuration option. This is the old way of configuring Tailwind CSS, and we recommend using the `tailwind.config.{ts,js}` file for configuration.

```ts title="modern.config.ts"
export default {
  tools: {
    tailwindcss: {
      content: ['./src/**/*.{js,jsx,ts,tsx}'],
    },
  },
};
```

If you are using both the `tailwind.config.{ts,js}` file and `style.tailwindcss` option, the configuration defined in `style.tailwindcss` will take precedence and override the content defined in `tailwind.config.{ts,js}`.

### Tailwind CSS Autocomplete

Tailwind CSS provides an official extension called [Tailwind CSS IntelliSense](https://github.com/tailwindlabs/tailwindcss-intellisense) for autocompletion of Tailwind CSS class names, CSS functions, and directives in VS Code.

You can follow the steps below to enable the autocomplete feature:

1. Install the [Tailwind CSS IntelliSense](https://github.com/tailwindlabs/tailwindcss-intellisense) extension in VS Code.
2. If the root directory of your project does not have a `tailwind.config.{ts,js}` file, you need to create one and write the Tailwind CSS configuration for your current project. Otherwise, the IDE plugin will not work correctly.

## Build Modes

When using Tailwind CSS, please note that there are significant differences between the bundle and bundleless modes in terms of the build artifacts.

:::tip
For definitions of bundle and bundleless, please refer to the ["In-depth understanding of build"](/guide/advance/in-depth-about-build).
:::

### Bundle Mode

In Bundle mode, a separate CSS file is generated, and the JS output does not automatically reference the CSS output file.

- Source code:

```tsx title="./src/index.tsx"
import './index.css';

export default () => {
  return <div className="bg-black">hello world</div>;
};
```

- Output code:

```js title="./dist/es/index.js"
// src/index.tsx
import { jsx } from 'react/jsx-runtime';
var src_default = () => {
  return /* @__PURE__ */ jsx('div', {
    className: 'bg-black',
    children: 'hello world',
  });
};
export { src_default as default };
```

```css title="./dist/es/index.css"
.bg-black {
  --tw-bg-opacity: 1;
  background-color: rgb(0 0 0 / var(--tw-bg-opacity));
}
/** some more... */
```

If you need to inject styles into the JS artifact, you can enable the [style.inject](/api/config/build-config#styleinject) option.

If you haven't enabled `style.inject`, you can also let users manually import the CSS file:

```js
import 'your-package/dist/es/index.css';
```

### Bundleless Mode

In bundleless mode, the CSS file is automatically imported in the artifact code without the need for additional processing.

- Output code:

```js title="./dist/es/index.js"
import { jsx as _jsx } from 'react/jsx-runtime';
import './index.css';
export default () =>
  /* @__PURE__ */ _jsx('div', {
    className: 'bg-black',
    children: 'hello world',
  });
```

## Class Name Prefix

You can add a class name prefix using the [prefix](https://tailwindcss.com/docs/configuration#prefix) option provided by Tailwind CSS. This helps avoid potential class name conflicts, such as when different versions of Tailwind CSS are used in different parts of an application or module.

For example, you can add the `foo-` prefix using the `prefix` option in `tailwind.config.js`:

```js title="tailwind.config.js"
module.exports = {
  prefix: 'foo-',
};
```

- Source Code:

```tsx title="./src/index.tsx"
import './index.css';

export default () => {
  return <div className="foo-bg-black">hello world</div>;
};
```

- Output Code:

```css title="./dist/es/index.css"
.foo-bg-black {
  --tw-bg-opacity: 1;
  background-color: rgb(0 0 0 / var(--tw-bg-opacity));
}
/** some more... */
```

## Usage Guide

Here are some usage examples of Tailwind CSS.

### HTML Class Names

Tailwind CSS supports adding styles to HTML tags through class names. **When using HTML class names, please note that the corresponding CSS styles of Tailwind CSS must be imported in advance.**

```tsx title="./src/index.tsx"
import './index.css';

export default () => {
  return <div className="bg-black">hello world</div>;
};
```

Generated styles (after bundling):

```css title="./dist/es/index.css"
.bg-black {
  --tw-bg-opacity: 1;
  background-color: rgba(0, 0, 0, var(--tw-bg-opacity));
}
/** some more... */
```

### `@apply`

Tailwind CSS provides the [`@apply`](https://v2.tailwindcss.com/docs/functions-and-directives#apply) directive, which allows us to inline the styles provided by Tailwind CSS into our own styles.

`@apply` can be used in CSS, Less, and Sass.

```css
.btn {
  @apply font-bold py-2 px-4 rounded;
}
```

However, there are some considerations when using it with Less and Sass:

#### Sass

When using Tailwind with Sass and there is an `!important` after `@apply`, interpolation should be used to ensure Sass compiles correctly.

- Won't work as expected:

```sass
.alert {
  @apply bg-red-500 !important;
}
```

- Will work as expected:

```sass
.alert {
  @apply bg-red-500 #{!important};
}
```

#### Less

When using Tailwind with Less, you cannot nest Tailwind's `@screen` directive.

- Won't work as expected:

```less
.card {
  @apply rounded-none;

  @screen sm {
    @apply rounded-lg;
  }
}
```

- Instead, use regular media queries and the `theme()` function to reference your screen sizes or simply avoid nesting your `@screen` directive.

```less title="Method 1"
// Use a regular media query and theme()
.card {
  @apply rounded-none;

  @media (min-width: theme('screens.sm')) {
    @apply rounded-lg;
  }
}
```

```less title="Method 2"
// Use the @screen directive at the top-level
.card {
  @apply rounded-none;

  @media (min-width: theme('screens.sm')) {
    @apply rounded-lg;
  }
}
```

## About `designSystem` config

`designSystem` is a deprecated configuration option in Modern.js Module.

Starting from Modern.js Module version MAJOR_VERSION.33.0, you can use the `theme` configuration option of Tailwind CSS as a replacement for `designSystem`. It is no longer necessary to split the `theme` configuration and set it on `designSystem`.

- Previous usage:

```ts title="modern.config.ts"
const { theme, ...rest } = tailwindConfig;

export default {
  style: {
    tailwindcss: rest,
  },
  designSystem: theme,
};
```

- Current usage:

```ts title="modern.config.ts"
export default {
  style: {
    tailwindcss: tailwindConfig,
  },
};
```
