|
| 1 | +# 原子化 CSS 技术分享讲稿:20 分钟版 |
| 2 | + |
| 3 | +这是一份独立的纯口播讲稿,适合现场直接照着讲,也适合按节奏自行增减段落。 |
| 4 | + |
| 5 | +## 现场使用方式 |
| 6 | + |
| 7 | +- `【页面】` 表示当前大屏建议停留的文档页。 |
| 8 | +- `【操作】` 表示你讲到这里时,建议在文档站里点到下一个页面。 |
| 9 | +- 如果现场节奏更快,可以只保留 `index`、`history`、`tailwind-core`、`best-practices`、`merge-and-variants`、`ai-friendly-and-demos` 这 6 个停靠点。 |
| 10 | + |
| 11 | +## 推荐点击路线 |
| 12 | + |
| 13 | +1. `/docs/tailwindcss` |
| 14 | +2. `/docs/tailwindcss/history` |
| 15 | +3. `/docs/tailwindcss/tailwind-core` |
| 16 | +4. `/docs/tailwindcss/best-practices` |
| 17 | +5. `/docs/tailwindcss/merge-and-variants` |
| 18 | +6. `/docs/tailwindcss/shadcn-ui` |
| 19 | +7. `/docs/tailwindcss/ai-friendly-and-demos` |
| 20 | +8. `/docs/tailwindcss/demos` |
| 21 | + |
| 22 | +## 正式讲稿 |
| 23 | + |
| 24 | +【页面|预计 4 分钟】 |
| 25 | + |
| 26 | +`/docs/tailwindcss` |
| 27 | + |
| 28 | +大家好,今天我想讲一个其实很多人都在用,但不一定真的想清楚的问题。 |
| 29 | + |
| 30 | +这个问题就是: |
| 31 | + |
| 32 | +为什么今天越来越多团队,会走向原子化 CSS? |
| 33 | + |
| 34 | +以及,Tailwind 这种方案,到底值不值得认真对待? |
| 35 | + |
| 36 | +我先不讲配置,也不讲 API。 |
| 37 | + |
| 38 | +我先给一个我自己的结论。 |
| 39 | + |
| 40 | +原子化 CSS 真正的价值,从来不只是“少写 CSS”。 |
| 41 | + |
| 42 | +如果只是为了少写几行样式,那很多方案都能做到。 |
| 43 | + |
| 44 | +Tailwind 真正厉害的地方,是它很容易把几件原本比较散的事情,收成一条工程链路。 |
| 45 | + |
| 46 | +比如设计约束。 |
| 47 | + |
| 48 | +比如类名组合。 |
| 49 | + |
| 50 | +比如组件封装。 |
| 51 | + |
| 52 | +比如构建产物。 |
| 53 | + |
| 54 | +甚至现在连 AI 生成代码,也能比较自然地接进来。 |
| 55 | + |
| 56 | +所以,如果今天你还把 Tailwind 理解成“一个类名很多的样式库”,那其实只看到了最表面的一层。 |
| 57 | + |
| 58 | +它更像一种组织样式的工程方法。 |
| 59 | + |
| 60 | +那要理解这件事,我们得先把它放回历史里看。 |
| 61 | + |
| 62 | +【操作|切页约 10 秒】 |
| 63 | + |
| 64 | +点击左侧「样式方案的演化」,进入: |
| 65 | + |
| 66 | +`/docs/tailwindcss/history` |
| 67 | + |
| 68 | +【这一段|预计 4 分钟】 |
| 69 | + |
| 70 | +前端样式方案,常见的发展路线,大概是这样的。 |
| 71 | + |
| 72 | +最早是 Raw CSS。 |
| 73 | + |
| 74 | +就是大家手写全局样式,靠命名约定和经验维持秩序。 |
| 75 | + |
| 76 | +然后是 Sass、Less 这样的预处理器,开始解决变量、混入和复用的问题。 |
| 77 | + |
| 78 | +再往后是 CSS Modules,把样式隔离交给编译器。 |
| 79 | + |
| 80 | +再之后是 CSS-in-JS,把样式和组件状态绑得更紧。 |
| 81 | + |
| 82 | +最后才是 Utility-first,也就是 Tailwind、UnoCSS 这样的原子化方案。 |
| 83 | + |
| 84 | +但这里我要停一下。 |
| 85 | + |
| 86 | +这个顺序,不代表线性替代。 |
| 87 | + |
| 88 | +不是说 Tailwind 出现了,前面的东西就都过时了。 |
| 89 | + |
| 90 | +现实不是这样。 |
| 91 | + |
| 92 | +现实是,这些方案今天依然并行存在。 |
| 93 | + |
| 94 | +内容站点、小项目、组件库、设计系统、微前端,它们各自最合适的方案,本来就不一样。 |
| 95 | + |
| 96 | +那为什么这几年 Utility-first 会越来越常见? |
| 97 | + |
| 98 | +因为它刚好特别适合现代前端的几个高频需求。 |
| 99 | + |
| 100 | +第一,它跟 design tokens 很容易对齐。 |
| 101 | + |
| 102 | +第二,它跟 JIT 和 content 扫描结合以后,产物比较好控。 |
| 103 | + |
| 104 | +第三,它很适合跟 `cva`、`tailwind-variants` 这种变体工厂结合。 |
| 105 | + |
| 106 | +第四,它对 AI 特别友好,因为原子类本身就是比较稳定、低歧义、可组合的语料。 |
| 107 | + |
| 108 | +但是,问题也在这里。 |
| 109 | + |
| 110 | +【操作|切页约 10 秒】 |
| 111 | + |
| 112 | +点击左侧「Tailwind 设计理念」,进入: |
| 113 | + |
| 114 | +`/docs/tailwindcss/tailwind-core` |
| 115 | + |
| 116 | +【这一段|预计 5 分钟】 |
| 117 | + |
| 118 | +原子化 CSS 很容易上手,所以也很容易被用乱。 |
| 119 | + |
| 120 | +很多团队一开始会觉得特别爽。 |
| 121 | + |
| 122 | +写页面快。 |
| 123 | + |
| 124 | +改 UI 也快。 |
| 125 | + |
| 126 | +然后过几个月,就开始出问题。 |
| 127 | + |
| 128 | +类名越来越长。 |
| 129 | + |
| 130 | +状态越来越散。 |
| 131 | + |
| 132 | +动态类越来越多。 |
| 133 | + |
| 134 | +评审越来越痛苦。 |
| 135 | + |
| 136 | +然后就有人下结论,说 Tailwind 只适合小项目。 |
| 137 | + |
| 138 | +但我觉得,不是这样的。 |
| 139 | + |
| 140 | +真正的问题不是 Tailwind 不行。 |
| 141 | + |
| 142 | +而是中间缺了一层约束。 |
| 143 | + |
| 144 | +这层约束,我觉得至少有三件事。 |
| 145 | + |
| 146 | +第一,先建设计体系,再写类名。 |
| 147 | + |
| 148 | +不要让每个组件自己发明颜色、间距和圆角。 |
| 149 | + |
| 150 | +色板、字号、间距、阴影这些值,应该先抽成 tokens。 |
| 151 | + |
| 152 | +不要在业务组件里到处写裸值。 |
| 153 | + |
| 154 | +第二,先收敛组件变体,再谈复用。 |
| 155 | + |
| 156 | +按钮、卡片、输入框,只要有 `size`、`tone`、`state` 这种变化,就应该集中到 `cva` 或 `tailwind-variants` 里。 |
| 157 | + |
| 158 | +不要在业务组件里反复拼大串 class。 |
| 159 | + |
| 160 | +第三,先验证产物,再相信感觉。 |
| 161 | + |
| 162 | +Tailwind 很多问题,不在运行时,而在构建阶段。 |
| 163 | + |
| 164 | +`content` 范围写太宽,动态类自由拼接,关系类嵌套太深,最后都会让 CSS 膨胀,让代码越来越难维护。 |
| 165 | + |
| 166 | +这里我还想单独点一个包。 |
| 167 | + |
| 168 | +就是 `tailwind-merge`。 |
| 169 | + |
| 170 | +很多人觉得它只是个小工具。 |
| 171 | + |
| 172 | +但只要你的组件允许外部传 `className` 覆盖,它就不是可选项,而是基础设施。 |
| 173 | + |
| 174 | +因为 Tailwind 最终的覆盖关系,不是简单按你 class 的先后顺序决定的,而是按它内部生成规则排序的。 |
| 175 | + |
| 176 | +所以如果没有 merge,你以为“最后一个类会生效”,其实未必。 |
| 177 | + |
| 178 | +这也是为什么我会说,一条成熟的 Tailwind 工程链路,应该长成这样: |
| 179 | + |
| 180 | +先有 tokens。 |
| 181 | + |
| 182 | +再有原子类。 |
| 183 | + |
| 184 | +再有 variants builder。 |
| 185 | + |
| 186 | +再有组件。 |
| 187 | + |
| 188 | +然后靠 content 精准扫描驱动 JIT。 |
| 189 | + |
| 190 | +最后再用 `tailwind-merge` 保证覆盖结果可预期。 |
| 191 | + |
| 192 | +这样 Tailwind 才真正从“写样式方式”,变成“组件工程的一部分”。 |
| 193 | + |
| 194 | +【操作|切页约 10 秒】 |
| 195 | + |
| 196 | +点击左侧「原子化 CSS 最佳实践」,进入: |
| 197 | + |
| 198 | +`/docs/tailwindcss/best-practices` |
| 199 | + |
| 200 | +【这一段|预计 2 分钟】 |
| 201 | + |
| 202 | +讲到这里,我们就能顺着理解,为什么 shadcn/ui 会有这么大影响力。 |
| 203 | + |
| 204 | +它的重要性,不在于它长得有多好看。 |
| 205 | + |
| 206 | +而在于它把一种模式推广开了。 |
| 207 | + |
| 208 | +无样式交互基座,比如 Radix。 |
| 209 | + |
| 210 | +再加 Tailwind 负责视觉。 |
| 211 | + |
| 212 | +再加 `tailwind-merge` 和 `cva` 负责变体和覆盖。 |
| 213 | + |
| 214 | +最后把源码直接放进项目里。 |
| 215 | + |
| 216 | +这个模式本质上是在说: |
| 217 | + |
| 218 | +组件的所有权,应该回到团队自己手里。 |
| 219 | + |
| 220 | +【操作|切页约 15 秒】 |
| 221 | + |
| 222 | +这里可以先点到「tailwind-merge、cva、tailwind-variants 精要」,停一下: |
| 223 | + |
| 224 | +`/docs/tailwindcss/merge-and-variants` |
| 225 | + |
| 226 | +然后顺手再点到: |
| 227 | + |
| 228 | +`/docs/tailwindcss/shadcn-ui` |
| 229 | + |
| 230 | +【这一段|预计 2 分钟】 |
| 231 | + |
| 232 | +再往后一步,就是 AI。 |
| 233 | + |
| 234 | +原子类为什么适合 AI? |
| 235 | + |
| 236 | +不是因为模型特别喜欢 Tailwind。 |
| 237 | + |
| 238 | +而是因为它更容易被约束。 |
| 239 | + |
| 240 | +你可以告诉模型,只能用哪些 tokens,只能用哪些组件,只能走哪些 variants。 |
| 241 | + |
| 242 | +你可以禁止它去拼任意动态类。 |
| 243 | + |
| 244 | +然后再用 lint、merge、build 和人工 review 去兜底。 |
| 245 | + |
| 246 | +这样 AI 写出来的代码,才可能进入正式工程。 |
| 247 | + |
| 248 | +【操作|切页约 10 秒】 |
| 249 | + |
| 250 | +点击左侧「AI 友好提示与 Demo 运行指南」,进入: |
| 251 | + |
| 252 | +`/docs/tailwindcss/ai-friendly-and-demos` |
| 253 | + |
| 254 | +【这一段|预计 3 分钟】 |
| 255 | + |
| 256 | +最后我收个尾。 |
| 257 | + |
| 258 | +今天这场分享,我最想留下的一句话是: |
| 259 | + |
| 260 | +不要把原子化 CSS 当成“省事的写法”。 |
| 261 | + |
| 262 | +要把它当成“更容易建立工程约束的入口”。 |
| 263 | + |
| 264 | +如果你的项目还很小,Raw CSS、BEM、Modules 都完全可以继续用。 |
| 265 | + |
| 266 | +如果你已经进入组件化和设计系统阶段,Tailwind 的价值会越来越明显。 |
| 267 | + |
| 268 | +但不管选哪条路,真正决定上限的,都不是类名形式。 |
| 269 | + |
| 270 | +而是 tokens、组件边界、变体管理和验证链。 |
| 271 | + |
| 272 | +当你这么理解它的时候,Tailwind 这件事,才算真的讲明白。 |
| 273 | + |
| 274 | +【操作|切页约 10 秒】 |
| 275 | + |
| 276 | +收尾时切到: |
| 277 | + |
| 278 | +`/docs/tailwindcss/demos` |
| 279 | + |
| 280 | +停在 Demo 总览页结束,方便后面自然接演示或者问答。 |
| 281 | + |
| 282 | +谢谢大家。 |
0 commit comments