跳到正文
灵动桌面框架
Esc
本栏目菜单

TailwindCSS 样式

灵动桌面框架使用 TailwindCSS 4(tailwindcss / @tailwindcss/vite ^4.2.1)处理原子化样式,与 Ant Design 组件配合使用。

配置

TailwindCSS 4 通过 Vite 插件接入,项目里没有 tailwind.config.js 和 postcss.config.js:

// vite.config.ts
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";

plugins: [react(), tailwindcss()],

样式入口是 src/styles/global.css,由 src/main.tsx 导入:

/* src/styles/global.css */
/* CSS Cascade Layers 顺序声明 —— 必须在 @import "tailwindcss" 之前,先声明者优先级更低 */
@layer theme, base, components, antd, utilities;

@import "tailwindcss";
@import "./variables.css";

html,
body,
#root {
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

body {
  font-family: var(--font-ui);
  font-size: var(--font-size);
  background: var(--bg-primary);
  color: var(--text-primary);
}

global.css 还定义了文本选区、细滚动条、链接颜色和 .overlay 遮罩层,全部引用 variables.css 中的变量。

CSS 设计令牌

src/styles/variables.css 是设计令牌的唯一来源,颜色类令牌通过 <html data-theme> 切换,暗色是默认值:

/* src/styles/variables.css(节选) */
:root,
:root[data-theme="dark"] {
  --bg-primary: #1a1a1c;
  --bg-secondary: #232325;
  --text-primary: #dcdcde;
  --text-secondary: #8a8a8d;
  --accent: #5090f0;
  --border: #353538;
  /* ... */
}

:root[data-theme="light"] {
  --bg-primary: #ffffff;
  --bg-secondary: #f5f5f7;
  --text-primary: #1a1a2e;
  --text-secondary: #5c5c6e;
  --accent: #2563eb;
  --border: #d9d9de;
  /* ... */
}

/* 通用令牌(不随主题切换) */
:root {
  --spacing-xs: 4px;
  --spacing-sm: 8px;
  --spacing-md: 12px;
  --spacing-lg: 16px;
  --radius-sm: 3px;
  --radius-md: 6px;
  --radius-lg: 8px;
  --radius-xl: 12px;
  --font-size: 13px;
  --sidebar-width: 220px;
  --header-height: 48px;
  /* ... */
}
类别令牌
背景--bg-primary --bg-secondary --bg-tertiary --bg-hover --bg-active
文本--text-primary --text-secondary --text-muted
品牌 / 状态--accent --accent-hover --danger --success --warning --info
边框 / 阴影--border --border-secondary --shadow-sm --shadow-md --shadow-lg
其他(随主题)--scrollbar-thumb --scrollbar-thumb-hover --selection-bg --selection-text --overlay-bg
通用--spacing-* --radius-* --transition-* --font-ui --font-mono --font-size* --sidebar-width --sidebar-collapsed-width --header-height --content-max-width

常用模式

页面容器

框架内置页面统一用居中窄栏,卡片之间用 mt-* 拉开:

<div className="max-w-2xl mx-auto">
  <Title level={3}>设置</Title>
  <Text type="secondary">应用配置管理</Text>

  <Card title="软件更新" className="mt-6">{/* ... */}</Card>
  <Card title="配置列表" className="mt-4">{/* ... */}</Card>
</div>

Flex 布局

{/* src/pages/about/index.tsx:加载中居中显示 */}
<div className="flex justify-center py-8">
  <Spin />
</div>

{/* src/components/layout/Sidebar.tsx:纵向撑满 + 标题居中 */}
<div className="flex flex-col h-full">
  <div className="h-12 flex items-center justify-center font-bold text-base">
    Agile Tauri
  </div>
</div>

颜色用 CSS 变量

颜色不要用 bg-blue-500、text-gray-500 这类写死色值的工具类,而是引用设计令牌,这样切换主题时自动跟随:

<div
  className="h-12 flex items-center justify-center"
  style={{
    borderBottom: `1px solid var(--border)`,
    color: "var(--text-primary)",
    background: "var(--bg-secondary)",
  }}
>
  Agile Tauri
</div>

与 Ant Design 配合

antd 6 通过 CSS-in-JS 在运行时注入样式。框架用两处配置把它放进 CSS 层,保证 Tailwind 工具类能覆盖 antd 组件默认样式:

  1. src/App.tsx 用 <StyleProvider layer>(来自 @ant-design/cssinjs)包住 ConfigProvider,antd 样式会注入到 @layer antd
  2. src/styles/global.css 首行声明层顺序 @layer theme, base, components, antd, utilities;:antd 排在 base 之后,不会被 Tailwind preflight 的重置样式冲掉;排在 utilities 之前,mt-6 等工具类可以直接覆盖 antd

两处缺一不可

少了 StyleProvider layer,antd 样式不进层,优先级高于所有层内样式;少了层顺序声明,antd 层会被追加到序列末尾。两种情况下,写在 antd 组件上的 Tailwind 类都会静默失效。

TailwindCSS 主要用于:

  • 间距和布局:p-3、mt-6、mx-auto、max-w-2xl、flex、grid
  • 文字样式:text-base、font-bold
  • 快速微调:rounded-lg、overflow-auto

Ant Design 负责:

  • 交互组件:Button、Table、Form、Modal 等
  • 主题一致性:通过 ConfigProvider 统一风格
{/* 混合使用示例:有了层顺序,不需要 ! 也能覆盖 antd 的默认外边距 */}
<Card title="系统信息" className="mt-6">
  <div className="flex items-center gap-3">
    <Avatar size={48} />
    <div>
      <Title level={5} className="mb-0">用户名</Title>
      <Text type="secondary">管理员</Text>
    </div>
  </div>
</Card>

不要用 dark: 前缀

TailwindCSS 4 的 dark: 默认跟随系统的 prefers-color-scheme,而框架没有用 @custom-variant 把它绑定到 data-theme。用户在应用内手动切到亮色、系统却是暗色时,dark: 样式仍会生效。主题相关的颜色一律用 CSS 变量。