之前学习过tailwindcss,看过它的文档,尝试过总结一下它的写法,但总结的不深入,同时在外包项目中使用过它,但都是只言片语的使用,不能使用它完成很复杂的样式功能。当看到别人写出很长的className时,我是真的不知道该怎么理解,这些样式代码到底是怎么组织起来的?为什么要这么组织?这么组织实现了什么功能?

image-20251105194149391

确实容易头晕眼花,我想找到一个抓手,而不是照着文档这里抄一抄那里抄一抄,没有方向。

https://www.youtube.com/watch?v=6biMWgD6_JY,这个课程解释了tailwind的原理,我想能够给我一点答案。

Introduction

image-20251105193034818

tailwind的理念是utility-first,utility:公共服务、使用程序,实用、有用。这里可以理解为实用工具优先。

具体意思就是tailwind提供具体的CSS实用功能,不需要人去想该怎么实现样式。

很多大公司(比如说openai、shopee、nasa)都在使用tailwind,不用担心学习了之后找工作时用不到。

How does Tailwind work?

every tailwind class is a predefined CSS rule, so it is reusable.

Tailwind Fundamentals Understanding the Basics

打开tailwind playground,写一段简单的代码:

image-20251105201447521

可以看到,有一个generated CSS部分,里面的utilities存放了我们实际使用的样式代码:

image-20251105201540893

上面的例子说明:tailwindcss generates styles on the fly, only for the classes we actually use.This keeps our CSS lean and efficient.

我们可以将鼠标悬浮到tailwindcss的classname上,查看这个样式的真实代码:

image-20251105201913479

那么我这里就有一个问题,在这里我可以看到generated CSS,但是我在项目中使用tailwindcss的时候,生成的样式在哪里存放呢?我怎么从来没有看到过呢?下面会讲。

The Just-In-Time(JIT) Compiler: Tailwind's Superpower

tailwindcss提供JIT编译器(compiler)功能,它会根据需求来生成样式,

Tailwind 不是一个“固定的 CSS 文件”库,而是一个 编译时(build-time)生成 CSS 的工具 它依赖 PostCSS,在构建阶段扫描你项目中的文件(HTML、JSX、TSX 等),然后只生成你实际用到的类名对应的 CSS 规则

这叫 JIT(Just-In-Time)编译模式

在 Next.js 项目中,大致流程如下:

  1. 你在组件中写:

  2. Tailwind 的构建工具(通过 postcss)扫描到这些类名。

  3. 它会即时生成对应的 CSS 规则,比如:

  4. 这些样式被打包到最终的 CSS 文件中,由 Next.js 自动注入页面 <head>

生成的 CSS 实际“存放”在哪里?

这要分情况看:

阶段CSS 的存放位置说明
🧪 开发模式 (next dev)内存中(Memory)Tailwind JIT 实时编译,CSS 不落盘。Next.js 通过内存注入样式(你在 .next/ 目录里看不到)。
⚙️ 构建模式 (next build)构建产物中Next.js 会将 Tailwind 编译出的 CSS 打包进 .next/static/css/ 目录(或内联进页面)。
🚀 生产部署时浏览器加载的最终静态文件在部署后,Tailwind 的 CSS 是优化过的,只包含用到的类。

✅ 换句话说:

  • 开发时 → CSS 在内存中动态生成。
  • 打包时 → CSS 被写入 .next/static/css/(通过 PostCSS + Next.js 编译流程)。

以下几个文件是 Tailwind 生成 CSS 的关键:

Layouts & Flex-box: Structuring Your UI

老师就是在tailwind playground里面讲解了一下flex和grid布局。

image-20251105203922422

如果不懂flex或者grid布局,老师推荐了两个游戏:https://flexboxfroggy.com/https://cssgridgarden.com/,帮助理解。

Media Queries & Responsive Design

重点:tailwind design是mobile first的,意味着在项目中写样式,应该由mobile样式写起,逐步完善到PC端的样式。

怎么完善呢?就是添加breakpoints prefix,然后看在不同屏幕下的效果。但是这样做非常麻烦,因为整个项目需要添加breakpoints的地方很多,而且哪些地方需要添加我还没有头绪。

那如果我的项目主要是适配PC端,我该怎么添加样式呢?问了一下chatgpt,如果PC端不需要适配小屏,那么默认样式按照PC端来写就行了,不用加breakpoints prefix,我看tailwind-landing-page-template-main这个tailwind模板项目也是这么做的,没有考虑小屏的情况。如果非要适配小屏,到时候就添加breakpoints前缀,慢慢改。

🧩 一、什么叫 “Mobile-first”

Tailwind 的“mobile-first”其实是说:

👉 默认写的样式是针对小屏(移动端)的。 然后通过断点前缀(sm:md:lg:xl: 等)逐步增强到更大的屏幕。

换句话说,Tailwind 的媒体查询是 “min-width” 模式(从小屏到大屏):


🧠 二、为什么这样设计

因为:


📱 三、例子:标准 mobile-first 写法

含义:

屏幕样式
默认(移动端)padding 0.5rem, text-sm
≥768px (md:)padding 1rem, text-base
≥1024px (lg:)padding 1.5rem, text-lg

Tailwind 会生成的 CSS 像这样👇:


💻 四、那如果你的项目主要是 PC 端 呢?

这时你有两种写法策略👇:


方式一:仍然使用 Mobile-first(推荐)

原因: Tailwind 的生态(组件库、插件、预设样式)全都默认按 mobile-first 思路组织。 即使你的目标是 PC 网页,仍建议按它的逻辑来写。

正确做法是:先把默认(无前缀)写成手机/基础样式,再在较大断点里“增强”为桌面样式。

示例:把桌面当作“增强层”

例子:

含义:默认 p-4(手机/小屏),当宽度 ≥ md(默认 768px)时变成 p-8(桌面更大间距)。


🛠️ 方式二:自己配置 “Desktop-first” 断点(不推荐但可行)

如果你非常确定永远不会支持移动端, 可以在 tailwind.config.js 中自定义 max-width 断点:

这样 md: 就变成 “在 767px 以下生效”。 但要注意,这会让你的项目与 Tailwind 官方组件生态不兼容(比如 Flowbite、DaisyUI、HeadlessUI)。


💡 五、实际建议

目标建议
项目同时支持移动端和 PC✅ 用默认的 mobile-first(标准写法)
纯 PC 内部系统(后台、管理端)✅ 默认写成 PC 样式,几乎不写响应式类(依旧 mobile-first)
仅适配大屏显示设备⚙️ 可以通过 @layer base 定义全局样式,或者重写断点配置

✳️ 总结一句话

Tailwind 的 “mobile-first” 是一种媒体查询逻辑: 默认样式用于最小屏幕, 通过 sm:md:lg: 逐步增强到大屏。

如果你做 PC 端项目,不需要改配置, 直接把默认样式当作 PC 样式写 就可以了。

老师在tailwind playground里面讲解了一下tailwind的breakpoints的使用。

image-20251105204920809

 

老师强调了,tailwindcss里面的样式如果不写前缀,默认是适配mobile devices,不要用sm:类名当作适配mobile devices,这个的意思是屏幕宽度大于640px才会生效。

image-20251106094239990

Dark Mode in Tailwind

image-20251106095137640

dark mode时的样式很好编写,只需要在类名前面添加dark:前缀即可。

怎么使用一个switch按钮来控制网页是否显示dark mode呢?可以这样做:

image-20251106100321984

比如说在nextjs项目里面,在globals.css里面,加上这一句@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));,然后在最外层的layout.tsx里面,html标签上加上data-theme={isDark},这个isDark可以设置为redux里面的变量,因为switch按钮应该写在nav组件里面了。

Custom Styles & Reusability

可以使用样式名-[自定义属性值]的方式,来自定义样式,比如说p-[16px]表示padding: 16px,text-[36px]表示字体大小36px。

但是这种使用方式很局限,因为字体大小项目的每个开发者可能随意设置,展示效果就非常不统一。

这时候就要考虑tailwind的config文件。直接在css文件里面,使用tailwind directives来编写想要的样式。

image-20251106101116034

参考https://tailwindcss.com/docs/theme

image-20251106101449722

tailwind还提供了很多functions和directives,可以让我们将一些重复性很高的代码,写出一个自定义的类名,这样用起来就只需要使用很少的类名即可。

比如说card最外层的div上面,有一些重复性很高的代码:

image-20251106102253274

就可以使用tailwind directives,@layer components来设置一个类名.card

image-20251106102348085

这样在div上只需要使用class="card"就可以了。

image-20251106102330208

 

使用@layer base可以定义一些标签的默认样式,这样在使用的时候,不需要指定任何类名,就可以展示这些样式:

image-20251106102656714

image-20251106104214770

Tailwind CSS Tips & Tricks

1、accent

设置accent color(强调色),比如说checkbox里面的选中颜色,可以通过class="accent-ping-500"来更改。

image-20251106104946558

2、Fluid Text

一般来说,我们使用breakpoints prefix来设置不同屏幕下的字体大小:

image-20251106105524413

但是之前说了,text-[]这种方式可以自定义字体大小,那么[]里面其实还可以写函数min()min()函数是CSS的内容,这里先不管,为了实现fluid text功能,可以这样写:

效果是这样的,可以看到字体大小变化的更顺畅了:

3、File

在设置<input type="file" />的样式的时候,因为原生的上传组件样式非常不好调整,需要先将原生的input隐藏掉,然后设置一个额外的元素来模拟上传组件。像这样:

image-20251106110213565

但是使用tailwindcss,你能够使用file:前缀,直接在input上面修改样式,非常简单:

image-20251106110337837

4、HighLight

假设我们想修改用户选择某些文字的时候的高亮色,可以使用selection:前缀。

5、less javascript

可以使用Open/closed state,来打开关闭<details> or <dialog>element。因为如果这里只是为了展示一些固定信息的话,确实不需要设置单独的变量。

image-20251106112213903

 

 

另外还有一点,how on earth can I remember all these tailwind classes?

image-20251106112404022

老师说,不用刻意记忆,经常使用就会形成肌肉记忆。

Fitness Project Details

这节课老师介绍它的进阶课程。等到老师发布了就可以看了。