---
sidebar_position: 2
---

# 使用 Tailwind CSS

[Tailwind CSS](https://tailwindcss.com/) 是一个以 Utility Class 为基础的 CSS 框架和设计系统，可以快速地为组件添加常用样式，同时支持主题样式的灵活扩展。

Modern.js Module 支持使用 Tailwind CSS 开发组件样式。

## 启用 Tailwind CSS

在 Modern.js Module 中使用 [Tailwind CSS](https://tailwindcss.com/)，你只需要按照以下步骤操作：

1. 在项目根目录下执行 `pnpm run new`，按照如下进行选择：

```text
? 请选择你想要的操作 启用可选功能
? 请选择功能名称 启用 「Tailwind CSS」 支持
```

成功开启后，你会看到 `package.json` 中新增了 `tailwindcss` 和 `@modern-js/plugin-tailwindcss` 依赖。

2. 在 `modern.config.ts` 中注册 Tailwind 插件:

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

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

3. 创建 `index.css` 文件，添加以下代码：

```css title="index.css"
/* base 和 components 是可选的，请酌情添加 */
@tailwind base;
@tailwind components;
@tailwind utilities;
```

:::info
根据需求不同，你可以选择性地导入 Tailwind CSS 提供的 CSS 样式。请参考 [`@tailwind` 文档](https://tailwindcss.com/docs/functions-and-directives#tailwind) 来了解 `@tailwind` 指令的详细用法。
:::

4. 引用 `index.css` 文件，比如在入口的 `src/index.jsx` 文件添加如下代码：

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

5. 然后即可在各个组件中使用 Tailwind CSS 提供的 Utility Class 了：

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

## 配置 Tailwind CSS

在 Modern.js Module 中，你有两种方式来配置 Tailwind CSS：

1. 使用 `tailwind.config.{ts,js}` 文件，该用法与 Tailwind CSS 的官方用法一致，请参考 ["Tailwind CSS - Configuration"](https://tailwindcss.com/docs/configuration) 来了解更多用法。

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

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

:::tip
请升级 Modern.js Module 到 >= MAJOR_VERSION.33.0 版本，以支持自动读取 `tailwind.config.{ts,js}` 文件。
:::

2. 使用 [style.tailwindcss](/api/config/build-config.html#styletailwindcss) 配置项，这是旧版本的用法，我们更推荐使用 `tailwind.config.{ts,js}` 文件进行配置。

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

如果你同时使用了 `tailwind.config.{ts,js}` 文件和 `style.tailwindcss` 选项，那么 `style.tailwindcss` 定义的配置会优先生效，并覆盖 `tailwind.config.{ts,js}` 中定义的内容。

## Tailwind CSS 自动补全

Tailwind CSS 官方提供了 [Tailwind CSS IntelliSense](https://github.com/tailwindlabs/tailwindcss-intellisense) 插件，用于在 VS Code 中自动补全 Tailwind CSS 的 class names、CSS functions 和 directives。

你可以参考以下步骤来启动自动补全功能：

1. 在 VS Code 中安装 [Tailwind CSS IntelliSense](https://github.com/tailwindlabs/tailwindcss-intellisense) 插件。
2. 如果项目的根目录没有 `tailwind.config.{ts,js}` 文件，那么你需要创建该文件，并写入当前项目的 Tailwind CSS 配置，否则 IDE 插件将无法正确生效。

## 构建模式

在使用 Tailwind CSS 时，请注意构建产物在 bundle 和 bundleless 两种模式下会有很大区别。

:::tip
关于 bundle 和 bundleless 的定义，可以查看 [「深入理解构建」](/guide/advance/in-depth-about-build)
:::

### Bundle 模式

在 Bundle 模式下，会生成一份单独的产物 CSS 文件，并且 JS 产物不会自动引用产物 CSS 文件。

- 源代码：

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

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

- 产物代码：

```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... */
```

如果你需要将样式注入 JS 产物中，可以开启 [style.inject](/api/config/build-config#styleinject) 选项。

如果你没有开启 `style.inject`，那么也可以让用户手动引用产物 CSS 文件：

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

### Bundleless 模式

在 Bundleless 模式下，默认会引用产物 CSS 文件，无须进行额外处理。

- 产物代码：

```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',
  });
```

## 类名前缀

你可以通过 Tailwind CSS 提供的 [prefix](https://tailwindcss.com/docs/configuration#prefix) 选项来添加类名前缀，这样可以避免潜在的类名冲突问题（比如 App 和 Module 使用了不同版本的 Tailwind CSS）。

例如，通过 `prefix` 选项添加 `foo-` 前缀：

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

- 源代码：

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

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

- 产物代码：

```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... */
```

## 用法介绍

下面是一些 Tailwind CSS 的用法示例。

### HTML 类名

Tailwind CSS 支持在 HTML 标签上通过类名的方式增加样式。**当使用 HTML 类名的时候，请注意必须要提前导入 Tailwind CSS 相应的 CSS 样式。**

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

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

样式产物（此时是 bundle 构建）：

```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 提供了 [`@apply`](https://v2.tailwindcss.com/docs/functions-and-directives#apply) 指令，可以通过它将 Tailwind CSS 提供的样式内联到我们编写的样式中。

`@apply` 可以用于 CSS、Less、Sass 中。

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

但是使用过程中，对于 Less 和 Sass 有些情况需要注意：

#### Sass

当将 Tailwind 与 Sass 一起使用时，`@apply` 后面存在 `!important` 的时候，需要使用插值来让 Sass 正确编译。

- 不能正常工作：

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

- 能够正常工作：

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

#### Less

在与 Less 一起使用 Tailwind 时，你不能嵌套 Tailwind 的 `@screen` 指令。

- 不能正常工作：

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

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

- 相反，使用常规的媒体查询和 `theme()` 函数来引用你的屏幕尺寸，或者干脆不要嵌套你的 `@screen` 指令。

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

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

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

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

## 关于 `designSystem` 配置

`designSystem` 是 Modern.js Module 中废弃的配置项。

从 Modern.js Module vMAJOR_VERSION.33.0 版本开始，你可以使用 Tailwind CSS 的 `theme` 配置项来代替 `designSystem`，不再需要将 `theme` 配置拆分并设置到 `designSystem` 上。

- 旧版本用法：

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

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

- 当前版本用法：

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