Tailwind CSS 核心概念篇 1. 实用优先基本原理 Tailwind CSS 采用实用优先的方法,这种方法不同于传统的 CSS 编写方式。在实用优先范式中,你直接在 HTML 元素上应用预定义的类,而不是创建自定义 CSS 规则。
1.1 传统 CSS 方法 vs Tailwind 方法 传统方法 :编写自定义 CSS 样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 <template > <div class ="chat-notification" > <div class ="chat-notification-logo-wrapper" > <img class ="chat-notification-logo" src ="/img/logo.svg" alt ="ChitChat Logo" > </div > <div class ="chat-notification-content" > <h4 class ="chat-notification-title" > ChitChat</h4 > <p class ="chat-notification-message" > You have a new message!</p > </div > </div > </template > <style > .chat-notification { display : flex; align-items : center; max-width : 24rem ; margin : 0 auto; padding : 1.5rem ; border-radius : 0.5rem ; background-color : #fff ; box-shadow : 0 20px 25px -5px rgba (0 , 0 , 0 , 0.1 ), 0 10px 10px -5px rgba (0 , 0 , 0 , 0.04 ); } .chat-notification-logo-wrapper { flex-shrink : 0 ; } .chat-notification-logo { height : 3rem ; width : 3rem ; } .chat-notification-content { margin-left : 1.5rem ; } .chat-notification-title { color : #1a202c ; font-size : 1.25rem ; line-height : 1.25 ; } .chat-notification-message { color : #718096 ; font-size : 1rem ; line-height : 1.5 ; } </style >
Tailwind 方法 :直接在 HTML 中使用实用类
1 2 3 4 5 6 7 8 9 <div class ="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-lg flex items-center gap-x-4" > <div class ="shrink-0" > <img class ="size-12" src ="/img/logo.svg" alt ="ChitChat Logo" > </div > <div > <div class ="text-xl font-medium text-black" > ChitChat</div > <p class ="text-slate-500" > You have a new message!</p > </div > </div >
1.2 实用优先方法的优势 优势 描述 无需发明类名 不用创建像 sidebar-inner-wrapper
这样的类名,只需使用 Tailwind 提供的实用类 CSS 不再增长 传统方法中,每添加一个新功能,CSS 文件就会变大;使用实用类,一切都可重用 更安全地进行更改 CSS 是全局性的,而 HTML 中的类是局部的,可以更改而不用担心破坏其他内容
1.3 与内联样式的区别 虽然实用优先方法看起来像内联样式,但有几个重要优势:
设计约束 :内联样式中,每个值都是 “魔术数字”;实用类使用预定义的设计系统,更容易构建视觉一致的界面响应式设计 :内联样式不能使用媒体查询,而 Tailwind 的响应式实用类可以轻松构建响应式界面悬停、焦点和其他状态 :内联样式无法定位悬停或焦点等状态,Tailwind 的状态变体使这变得简单1 2 <button class ="px-4 py-1 text-sm text-purple-600 font-semibold rounded-full border border-purple-200 hover:text-white hover:bg-purple-600 hover:border-transparent focus:outline-none focus:ring-2 focus:ring-purple-600 focus:ring-offset-2" > Message</button >
1.4 可维护性考虑 使用实用优先方法最大的可维护性问题是管理常见的实用类组合。这可以通过以下方式解决:
提取组件和局部模板 1 2 3 4 5 6 <!-- PrimaryButton.vue --> <template> <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"> <slot/> </button> </template>
使用编辑器多光标编辑和简单循环 多光标编辑详解 多光标编辑是在同一个文件中处理重复样式的高效方法,无需创建组件或额外的抽象层。
实例演示:
假设你有一个导航栏,其中包含多个相似样式的链接:
1 2 3 4 5 6 <nav class ="flex space-x-4" > <a href ="/home" > Home</a > <a href ="/about" > About</a > <a href ="/services" > Services</a > <a href ="/contact" > Contact</a > </nav >
现在你需要给所有链接添加相同的样式。使用多光标编辑:
在 VS Code 中,按住 Alt
(Windows) 或 Option
(Mac) 键,然后在每个 <a>
标签后点击鼠标 当你在所有需要的位置都有光标后,开始输入 class="
,然后添加所需的样式类 所有选择位置将同时更新 结果如下:
1 2 3 4 5 6 <nav class ="flex space-x-4" > <a href ="/home" class ="px-4 py-2 text-gray-700 hover:text-gray-900 hover:bg-gray-100 rounded" > Home</a > <a href ="/about" class ="px-4 py-2 text-gray-700 hover:text-gray-900 hover:bg-gray-100 rounded" > About</a > <a href ="/services" class ="px-4 py-2 text-gray-700 hover:text-gray-900 hover:bg-gray-100 rounded" > Services</a > <a href ="/contact" class ="px-4 py-2 text-gray-700 hover:text-gray-900 hover:bg-gray-100 rounded" > Contact</a > </nav >
循环处理详解 当元素在页面上重复出现但在代码中只需定义一次时,循环是最有效的方法。
实例演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <!-- Vue 示例 --> <template> <nav class="flex space-x-4"> <a v-for="item in navItems" :key="item.path" :href="item.path" class="px-4 py-2 text-gray-700 hover:text-gray-900 hover:bg-gray-100 rounded" > {{ item.name }} </a> </nav> </template> <script> export default { data() { return { navItems: [ { name: 'Home', path: '/home' }, { name: 'About', path: '/about' }, { name: 'Services', path: '/services' }, { name: 'Contact', path: '/contact' } ] } } } </script>
2. 悬停、焦点和其他状态 Tailwind 中的每个实用类都可以通过添加修饰符来有条件地应用,这些修饰符描述你想要定位的条件。
2.1 基本用法 1 2 3 4 <button class ="bg-sky-500 hover:bg-sky-700 ..." > Save changes </button >
传统 CSS 与 Tailwind 的区别:
1 2 3 4 5 6 .btn-primary { background-color : #0ea5e9 ; } .btn-primary :hover { background-color : #0369a1 ; }
1 2 3 4 5 6 .bg-sky-500 { background-color : #0ea5e9 ; } .hover \:bg-sky-700 :hover { background-color : #0369a1 ; }
2.2 修饰符类型 Tailwind 包含多种类型的修饰符:
2.2.1 伪类修饰符 修饰符 描述 示例 hover:
鼠标悬停时 hover:bg-blue-700
focus:
元素获得焦点时 focus:outline-none
active:
元素被点击时 active:bg-blue-800
first:
第一个子元素 first:pt-0
last:
最后一个子元素 last:pb-0
odd:
奇数子元素 odd:bg-gray-100
even:
偶数子元素 even:bg-white
disabled:
禁用状态 disabled:opacity-50
required:
必填状态 required:border-red-500
invalid:
无效状态 invalid:border-red-500
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" /> <meta name ="viewport" content ="width=device-width, initial-scale=1.0" /> <title > Document</title > <script src ="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4" > </script > </head > <body > <button class ="bg-blue-400 hover:bg-blue-500 active:bg-blue-600 text-white px-4 py-2 rounded-md" > 按钮</button > </body > </html >
2.2.2 基于父元素状态的样式 (group-*) 当你需要根据 父元素 的状态来设置 子元素 的样式时,在父元素上添加 group
类,然后在子元素上使用 group-*
修饰符。
修饰符 描述 示例 group-hover:
父元素 group
被悬停时 group-hover:text-white
group-focus:
父元素 group
获得焦点时 group-focus:ring-2
group-active:
父元素 group
被点击时 group-active:bg-blue-100
group/{name}:
用于嵌套 group
时命名 group-hover/item:text-blue-500
示例:
当鼠标悬停在作为父元素的 <div>
上时,图标和文本的颜色会改变。
1 2 3 4 5 6 <a href ="#" class ="group block p-4 border" > <div > <h5 class ="text-gray-900 group-hover:text-blue-600" > 首页</h5 > <p class ="text-gray-500 group-hover:text-blue-400" > 查看应用概览</p > </div > </a >
2.2.3 基于兄弟元素状态的样式 (peer-*) 当你需要根据一个 兄弟元素 的状态来设置 另一个兄弟元素 的样式时,在前一个兄弟元素上添加 peer
类,然后在目标元素上使用 peer-*
修饰符。
⚠️ 注意 :peer
修饰符只对 后续 的兄弟元素生效,这是由 CSS 的工作方式决定的。
修饰符 描述 示例 peer-hover:
peer
兄弟元素被悬停时peer-hover:text-green-500
peer-focus:
peer
兄弟元素获得焦点时peer-focus:visible
peer-checked:
peer
兄弟元素 (如复选框) 被选中时peer-checked:bg-blue-500
peer-invalid:
peer
兄弟元素 (如输入框) 内容无效时peer-invalid:block
peer-disabled:
peer
兄弟元素被禁用时peer-disabled:opacity-50
示例:
当 <input>
元素进入 focus 状态,后面的提示信息 <p>
才会变得可见。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <div class ="space-y-2" > <h2 class ="text-lg font-semibold" > peer-focus 焦点效果</h2 > <div class ="space-y-2" > <input type ="text" class ="peer w-full px-3 py-2 border rounded focus:ring-2 focus:ring-blue-500" placeholder ="点击输入框获得焦点" /> <p class ="text-gray-400 peer-focus:text-blue-500 peer-focus:visible invisible" > 输入框已获得焦点! </p > </div > </div >
⚠️ 注意 :peer
标记只能用于 前面的 兄弟元素,因为 CSS 的相邻兄弟选择器的工作方式。
2.3 伪元素修饰符 修饰符 描述 示例 before:
::before
伪元素before:content-['*']
after:
::after
伪元素after:content-['↗']
placeholder:
占位符文本 placeholder:italic
file:
文件输入按钮 file:bg-violet-50
marker:
列表标记 marker:text-sky-400
selection:
文本选择 selection:bg-fuchsia-300
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" /> <meta name ="viewport" content ="width=device-width, initial-scale=1.0" /> <title > Document</title > <script src ="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4" > </script > </head > <body > <div class ="container mx-auto p-8" > <h1 class ="text-3xl font-bold mb-6 text-blue-600" > Tailwind CSS 伪元素和修饰符演示 </h1 > <div class ="mb-8" > <h2 class ="text-xl font-semibold mb-3" > before: 修饰符</h2 > <p class ="before:content-['*'] before:text-red-500 before:mr-1 text-gray-700" > 这是一个必填字段,使用 before 添加星号 </p > </div > <div class ="mb-8" > <h2 class ="text-xl font-semibold mb-3" > after: 修饰符</h2 > <a href ="#" class ="text-blue-500 after:content-['↗'] after:ml-1" > 外部链接示例 </a > </div > <div class ="mb-8" > <h2 class ="text-xl font-semibold mb-3" > placeholder: 修饰符</h2 > <input type ="text" placeholder ="斜体占位符文本" class ="border p-2 rounded placeholder:italic placeholder:text-gray-400 w-64" /> </div > <div class ="mb-8" > <h2 class ="text-xl font-semibold mb-3" > file: 修饰符</h2 > <input type ="file" class ="file:bg-violet-50 file:border-0 file:py-2 file:px-4 file:rounded file:text-violet-700 file:font-semibold hover:file:bg-violet-100" /> </div > <div class ="mb-8" > <h2 class ="text-xl font-semibold mb-3" > marker: 列表标记 修饰符</h2 > <ul class ="list-disc pl-6 marker:text-sky-400" > <li > 第一个列表项</li > <li > 第二个列表项</li > <li > 第三个列表项</li > </ul > </div > <div class ="mb-8" > <h2 class ="text-xl font-semibold mb-3" > selection: 修饰符</h2 > <p class ="selection:bg-fuchsia-300 selection:text-fuchsia-900" > 选择这段文本查看自定义选择效果。尝试用鼠标选择这些文字,会显示自定义的背景色和文字颜色。 </p > </div > </div > </body > </html >
3. 响应式设计 Tailwind 提供了强大的响应式设计功能,通过使用响应式修饰符,你可以轻松创建适应不同屏幕尺寸的界面。
3.1 移动优先方法 Tailwind 采用移动优先的策略,这意味着不带响应式修饰符的实用类首先应用于所有屏幕尺寸,然后使用响应式修饰符可以在特定断点上覆盖这些样式。
1 2 3 4 <div class ="grid grid-cols-3 md:grid-cols-4 lg:grid-cols-6" > </div >
3.2 默认断点 修饰符 屏幕宽度 CSS sm:
640px @media (min-width: 640px) { ... }
md:
768px @media (min-width: 768px) { ... }
lg:
1024px @media (min-width: 1024px) { ... }
xl:
1280px @media (min-width: 1280px) { ... }
2xl:
1536px @media (min-width: 1536px) { ... }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" /> <meta name ="viewport" content ="width=device-width, initial-scale=1.0" /> <title > Document</title > <script src ="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4" > </script > </head > <body > <div class ="p-8" > <div class ="bg-red-400 sm:bg-blue-400 md:bg-green-400 lg:bg-yellow-400 xl:bg-purple-400 2xl:bg-pink-400 p-4 rounded-lg text-white text-center" > <p class ="text-sm sm:text-base md:text-lg lg:text-xl xl:text-2xl 2xl:text-3xl" > 响应式断点演示 </p > <p class ="mt-2 text-xs sm:text-sm md:text-base lg:text-lg xl:text-xl 2xl:text-2xl" > 调整浏览器宽度查看不同断点效果 </p > </div > </div > </body > </html >
4. 深色模式 Tailwind 包含一个内置的 dark
变体,使你可以在深色模式下轻松设置不同样式。
4.1 基本用法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" /> <meta name ="viewport" content ="width=device-width, initial-scale=1.0" /> <title > Document</title > <script src ="https://cdn.tailwindcss.com" > </script > <script > tailwind.config = { darkMode : "selector" , }; </script > </head > <body > <button id ="theme-toggle" class ="mb-4 px-4 py-2 bg-slate-200 dark:bg-slate-700 text-slate-800 dark:text-slate-200 rounded-md hover:bg-slate-300 dark:hover:bg-slate-600" > 切换暗色模式 </button > <div class ="bg-white dark:bg-slate-800 rounded-lg px-6 py-8 ring-1 ring-slate-900/5 shadow-xl" > <h3 class ="text-slate-900 dark:text-white mt-5 text-base font-medium tracking-tight" > Writes Upside-Down </h3 > <p class ="text-slate-500 dark:text-slate-400 mt-2 text-sm" > The Zero Gravity Pen can be used to write in any orientation, including upside-down. </p > </div > </body > <script > document .getElementById ("theme-toggle" ) .addEventListener ("click" , function ( ) { document .documentElement .classList .toggle ("dark" ); }); </script > </html >
4.2 深色模式策略 默认情况下,Tailwind 使用 prefers-color-scheme
CSS 媒体特性来检测用户的系统偏好。你可以在 tailwind.config.js
中配置深色模式策略:
4.2.1 媒体查询策略(默认) 1 2 3 4 5 module .exports = { darkMode : 'media' , }
4.2.2 类选择器策略(手动切换) 1 2 3 4 5 module .exports = { darkMode : 'selector' , }
使用 selector
策略时,dark:
类将在 HTML 树中的早期存在 dark
类时应用:
1 2 3 4 5 6 7 8 9 <html class ="dark" > <body > <div class ="bg-white dark:bg-black" > </div > </body > </html >
4.3 手动切换深色模式 通过 JavaScript 来控制深色模式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 if (localStorage .getItem ('darkMode' ) === 'dark' || (!localStorage .getItem ('darkMode' ) && window .matchMedia ('(prefers-color-scheme: dark)' ).matches )) { document .documentElement .classList .add ('dark' ); } else { document .documentElement .classList .remove ('dark' ); } function toggleDarkMode ( ) { if (document .documentElement .classList .contains ('dark' )) { document .documentElement .classList .remove ('dark' ); localStorage .setItem ('darkMode' , 'light' ); } else { document .documentElement .classList .add ('dark' ); localStorage .setItem ('darkMode' , 'dark' ); } }
5. 重用样式 随着项目的增长,你会发现自己重复使用相同的实用类组合。以下是几种重用样式的方法:
5.1 提取组件和模板部分 对于需要在多个文件中重用的样式,最好的策略是创建组件(如果使用前端框架)或模板部分(如果使用模板语言)。
1 2 3 4 5 6 7 8 function Button ({ children } ) { return ( <button className ="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" > {children} </button > ); }
5.2 使用 @apply 提取样式 当创建模板部分感觉过重时,可以使用 Tailwind 的 @apply
指令将重复的实用类模式提取到自定义 CSS 类中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" /> <meta name ="viewport" content ="width=device-width, initial-scale=1.0" /> <title > Document</title > <script src ="https://cdn.tailwindcss.com" > </script > <style type ="text/tailwindcss" > @layer components { .btn-base { @apply px-4 py-2 rounded font-medium transition-colors; } } </style > </head > <body class ="p-8 space-y-4" > <button class ="btn-base bg-blue-500 hover:bg-blue-600 text-white" > 蓝色按钮 </button > <button class ="btn-base bg-green-500 hover:bg-green-600 text-white" > 绿色按钮 </button > <button class ="btn-base bg-red-500 hover:bg-red-600 text-white" > 红色按钮 </button > <button class ="btn-base bg-gray-200 hover:bg-gray-300 text-gray-800" > 灰色按钮 </button > </body > </html >
⚠️ 注意 :避免过早的抽象化。不要仅仅为了让 HTML 看起来更整洁而使用 @apply
。这样会丢失 Tailwind 提供的工作流和维护优势。
6. 添加自定义样式 6.1 自定义主题 在 tailwind.config.js
文件中自定义颜色、间距、排版和断点等:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 module .exports = { theme : { extend : { colors : { primary : '#3490dc' , secondary : '#ffed4a' , danger : '#e3342f' , }, spacing : { '72' : '18rem' , '84' : '21rem' , '96' : '24rem' , } } } }
6.2 使用任意值 当你需要突破设计约束时,使用方括号标记法生成具有任意值的类:
1 2 3 4 5 6 7 <div class ="top-[117px] lg:top-[344px]" > </div > <div class ="bg-[#bada55] text-[22px] before:content-['Festivus']" > </div >