说明:此系列文章是个人对Tailwind CSS官方文档的翻译,不是很严谨,请谅解。
提取组件
处理重复、使工具类优先的项目更容易维护
Tailwind鼓励使用工具类优先的工作流程,该流程最初只使用应用程序类以避免过早抽离的情况。
当项目扩大时,不可避免地会再项目的不同地方重复使用一些工具类组合来创建相同的组件。尤其是按钮、表单、徽章这一类的小组件。
在很多组件实例中同时搞那么一大长串的工具类名,很快就变成了不小的工作量了。当开始遇到这种情况的时候,抽离组件就成了不二之选。
提取HTML 组件
定义一个UI组件所需的信息都能承载在CSS中几乎是不可能的——一般来讲总会用到某些很重要的相关的HTML结构。
:x:提取复杂的组件时,避免依赖CSS 类
<style>
.vacation-card {/* ... */}
.vacation-card-info {/* ... */}
.vacation-card-eyebrow {/* ... */}
.vacation-card-title {/* ... */}
.vacation-card-price {/* ... */}
</style>
<!-- Even with custom CSS, you still need to duplicate this HTML structure -->
<div class="vacation-card">
<img class="vacation-card-image" src="..." alt="Beach in Cancun">
<div class="vacation-card-info">
<div>
<div class="vacation-card-eyebrow">Private Villa</div>
<div class="vacation-card-title">
<a href="/vacations/cancun">Relaxing All-Includive Resort in Cancun</a>
</div>
<div class="vacation-card-price">$299 USD per night</div>
</div>
</div>
</div>
因此,最好将可复用的片段抽取到模板片段或者Javascript 组件中,而不是写自定义CSS类。
通过为模板创建唯一的事实来源,就可以使用工具类,而却不用在项目的不同地方复制重读的CSS代码片段。
:white_check_mark:出啊u女鬼剑模板片段或JavaScript组件
<!-- 实际应用 -->
<VacationCard
img="..."
imgAlt="..."
eyebrow="..."
title="..."
pricing="..."
url="..."
/>
<!-- ./components/VacationCard.vue -->
<template>
<div>
<img class="rounded" :src="img" :alt="imgAlt">
<div class="mt-2">
<div>
<div class="text-xs text-gray-600 uppercase font-bold">
{{ eyebrow }}
</div>
<div class="font-bold text-gray-700 leading-snug">
<a :href="url" class="hover:underline">{{ title }}</a>
</div>
<div class="mt-2 text-sm text-gray-600">{{ pricing }}/div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['img', 'imgAlt', 'eyebrow', 'title', 'pricing', 'url']
}
</script>
上例使用的框架是vue,但是在react components, ERB partials, Blade components, Twig includes中也一样可以这么用。
使用 @apply 指令提取 CSS 组件
对于像按钮、表单这样的组件来说,专门创建一个模板片段或者JavaScript组件有时候显得过于笨重,而简单的CSS类就轻巧的多。
在这种情况西,就可以使用tailwind的@apply
指令将常见的工具模式很轻松地提取成 CSS 组件类。
如下例,使用@apply
将现存的工具类提取成.btn
类:
<button class="btn-blue">
Button
</button>
<style>
.btn-blue {
@apply bg-blue-500 text-white font-bold py-2 px-4 rounded;
}
.btn-blue:hover {
@apply bg-blue-700;
}
</style>
注意,像hover:,focus:,{screen}:
这类的变体不能被直接 apply,所以得用工具类的普通版本对相应的 伪类选择器或媒体查询进行apply。
这种类应该直接添加在@tailwind component
之后后面,以避产生免特异性问题。
:x:避免将自定义组件类写在CSS末尾
:white_check_mark:将自定义组件类卸载utilities前面
@tialwind base;
@tailwind components;
/* 要写在这个位置 */
.btn-blue {
@apply bg-blue-500 text-white font-bold py-2 px-3 rounded;
}
.btn-blue:hover {
@apply bg-blue-700;
}
@tailwind utilities;
/* 不要写在这最后 */
保持可组合性
假设有两个这样的按钮:
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Button
</button>
<button class="bg-gray-400 hover:bg-gray-500 text-gray-800 font-bold py-2 px-4 rounded">
Button
</button>
像下面这样给这两个按钮实现组件类估计看起来挺不错的:
.btn-blue {
@apply bg-blue-500 text-white font-bold py-2 px-4 rounded;
}
.btn-blue:hover {
@apply bg-blue-700;
}
.btn-gray {
@apply bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded;
}
.btn-gray:hover {
@apply bg-gray-500;
}
这种方式的问题在于还是有可能造成令人抓狂的重复。
如果你突发奇想要换掉网站上所有按钮的padding, font weight, border radius 等风格,你还得一个一个去改那些class。
所以说,最好是把相同的部分另外抽离到一个类中:
.btn {
@apply font-bold py-2 px-4 rounded;
}
.btn-blue {
@apply bg-blue-500 text-white;
}
.btn-blue:hover {
@apply bg-blue-700;
}
.btn-gray {
@apply bg-gray-400 text-gray-800;
}
.btn-gray:hover {
@apply bg-gray-500;
}
这样的话你啥时候想给一个按钮规定样式的话,就用两个类。
<button class="btn btn-blue">
Button
</button>
<button class="btn btn-gray">
Button
</button>
这样的话,想改公用风格的时候,只需要改.btn 类里面这一处就ok了。
而且还能在你想添加个别样式特殊的按钮的时候不用在必须去重新创建一个新的组件类,也不用再重写一遍那一大长串公用的样式:
<button class="btn bg-green-500 hover:bg-green-400 text-white">
Button
</button>
编写组件插件
除了直接再CSS文件里面写组件类之外,也可以通过写自定义插件来将组件类添加到tailwind中:
//tailwind.config.js
const plugin = require('tailwindcss/plugin')
module.exports = {
plugin: [
plugin(function({ addComponents }){
const buttons = {
'.btn': {
padding: '.5rem 1rem',
borderRadius: '.25rem',
fontWeight: '600',
},
'.btn-blue': {
backgroundColor: '#3490dc',
color: '#fff',
'&:hover': {
backgroundColor: '#2779bd'
}
},
'btn-red': {
backgroundColor: '#e3342f',
color: '#fff',
'&:hover': {
backgroundColor: '#cc1f1a'
},
},
}
addComponents(buttons)
})
]
}
如果你想把你自定义的 Tailwind 组件作为一个库来发布,或者想使多个项目之间对组件的共享更简易的话,写插件的方法就很不错了。