由于Tailwind不像MUI,Bootstrap等框架一样有自己的UI组件库。因此在项目开发的时候,经常需要自己根据基本的Tailwind类来定义一个组件库,比如按钮,Card等等。
卡片组件
定义卡片
如果要定义一个卡片,需要考虑以下因素:
- 圆角:使用rounded类,如果想要更改圆角半径,可以使用其他相关类,比如:round-full
- div容器和图片的覆盖:如果外层div设置为圆角,但图片未设置圆角,默认情况下图片的方角将会覆盖外层div的圆角,因此可以在外层div上应用overflow-hidden类
- 添加阴影,可以使用shadow类
- 宽度:可以进行自适应设置,比如w-80 sm:w-96
- object-cover: 当屏幕尺寸发生变化时,图片比例不会被拉伸,而是会zoom in/out
- 设置圆角标题div块定位在屏幕左上角:可以在外层div设置relative定位,内层设为absolute定位
最终代码:
<div class="rounded-lg overflow-hidden shadow-lg w-80 sm:w-96 relative">
<img src="images/marguerite.jpg" alt="Marguerite" class="w-full h-32 sm:h-48 object-cover"/>
<div>
<span class="font-bold">Rare flower desc</span>
<span class="block text-gray-500 text-sm">Origin: xxx</span>
</div>
<div class="font-bold rounded-full p-3 top-1 ml-1 mt-1 absolute">
<span>£4.99</span>
</div>
</div>使用@apply
目前的做法有些问题。当我们需要多次使用卡片时,所有的样式定义都需要重复,这就不便于后续维护。为了解决这个问题,可以使用@apply来应用所有对应样式。
.card {
@apply rounded-lg overflow-hidden shadow-lg w-80 sm:w-96 relative;
}
.card-title {
@apply font-bold rounded-full p-3 top-1 ml-1 mt-1 absolute
}
.card-desc {
@apply block text-gray-500 text-sm
}那么在后面的div中只需要引用card, card-title, card-desc三个类就可以了。
其他类似的方法
在Tailwind中,还可以使用@screen来针对不同尺寸屏幕应用样式:
@screen sm {
.btn {
@apply inline-block px-5 py-2 rounded-lg
}
}注意事项
在使用自定义样式的时后,这些样式和@tailwind utilities的次序是很重要的。应该这样做:
@tailwind base;
@tailwind components;
/* 自定义样式 */
.card {
@apply rounded-lg overflow-hidden shadow-lg w-80 sm:w-96 relative;
}
// ...
@tailwind utilities;尽量不要把”@tailwind utilities;”放在自定义样式的前面。原因在于:如果使用了.card类的话,同时又想使用一些行内样式:
- 如果”@tailwind utilities;”在自定义样式后面,行内样式会覆盖.card所定义的样式。(期待的行为)
- 如果自定义样式在后面,则会覆盖行内样式(不期待的行为)。
关于设计的几个考虑
antialiased
为了在高清显示器上出现最好效果,在顶级元素上使用antialiased。
<div id="root" class="antialiased">
</div> 关于颜色
不建议使用黑色,而使用text-gray-900,这样看起来更加自然。
关于字体
font-bold显得有些过于突兀,可以考虑是用font-semibold
作为卡片title,可以考虑使用text-lg / text-xl
对于卡片正文部分:
- 颜色的话,可以考虑相对较淡的颜色,比如:text-gray-700(默认为text-gray-900)
- 字体大小:可以考虑text-sm或者text-xs uppercase font-semibold tracking-wides组合
如果正文部分有多行的话,可以考虑标题的位置,比如:
<div>正文第一行</div>
<h4>标题</h4>
<div>正文第二行</div>
<div>正文第三行</div>
<div>正文第四行</div>关于行间距
一般情况下,行间距肯定要小于padding。
如果需要,可以调整行间距:
- leading-tight
- leading-snug
如果标题过长,也可以使用truncate类来截断对应的文本:
- truncate
最终示例
<div class="bg-white border rounded overflow-hidden">
<img />
<div class="p-5">
<div class="text-gray-600 text-xs uppercase font-semibold tracking-wide">
short desc
</div>
<h4 class="font-semibold text-lg leading-tight truncate">
Flow name
</h4>
<div class="mt-1">
£4.99
</div>
<div class="mt-4">
<span class="text-real-500 font-semibold">
5 stars
</span>
<span class="text-gray-600 text-sm">
/ 139 reviews
</span>
</div>
</div>
</div> 针对@apply样式的重用
如果需要定义一些重用性的样式,需要考虑把相同属性抽取出来单独定义:
.btn {
@apply ...
}
.btn-indigo {
@apply bg-indigo-600;
}
.btn-blue {
// ...
}按钮
如果要定义按钮,同样,应该把所有按钮的通用样式抽取出来,放在styles.pcss中,比如:
.button {
@apply rounded py-1 px-2 text-xs cursor-pointer;
}然后在使用按钮的时候直接使用这个类:
<div class="button border-primary md:border-2">Submit</a>也可以使用CSS的伪类:
.button:hover {
...
}对于按钮的话,我们经常会需要类似这样的样式:
- hover:bg-indigo-500: 当鼠标悬停时更改背景色
- focus:outline-none
- focus:shadow-outline
- active:bg-indigo-600: 当单击时更改按钮样式。
只不过需要注意的是,要想使用active对应的样式,需要更改tailwind.config.js。需要注意,必须把所有需要的variant都设置好,同时其次序也不能随便更改。
// ...
variants: {
backgroundColor: ['responsive','hover','focus','active']
}
// ...我们还可以将md:和hover结合使用:
hover:bg-indigo-400 md:hover:bg-indigo-600注意:hover:并不能和所有样式组合一起工作。比如,在默认情况下,hover:text-2xl不会正常工作,因为这种使用方式并不常见。如果想要这样使用的话,同样需要更改tailwind.config.js:
variants: {
fontSize: ['responsive', 'hover']
}图标
参考网站:https://heroicons.com/
SVG优化工具:https://jakearchibald.github.io/svgomg/
图标的使用非常简单,只要在上面网站单击对应的图标,就会将图标对应的SVG复制到剪贴板中。
<div class="product-price">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 inline" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 9a2 2 0 10-4 0v5a2 2 0 01-2 2h6m-6-4h4m8 0a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<span>5.99</span>
</div>如果想要更改图标颜色,可以去掉其fill属性,并在其class属性上添加:
<div class="h-6 w-6 fill-current text-red-500">
...
</div> 以Vue.js为例,如果想要添加五颗星的话,可以:
徽章
<div class="flex items-baseline">
<span class="inline-block bg-gray-500 text-white text-xs px-2 rounded uppercase font-semibold tracking-wide">Breaking news</span>
<div>
...
</div>
</div>图片

- h-48 w-full: 通过这种方式来限定图片尺寸
- object-cover: 保持图片缩放比例,占据所有可用空间
- object-center: 从中央位置剪切图片,还可以有object-left/object-top/object-right/object-bottom等
需要注意:IE11不支持以上属性,可以使用背景图来解决。
<div class="h-48 bg-cover bg-center" :style="{ backgroundImage: `url('${image_url}')`}">但需要权衡一下这两种方式的优缺点:
- 使用img标签:更好的accessibility,screen reader可以识别图片标记,但IE11不支持
- 使用背景图片,浏览器兼容性更好,但screen reader不能识别
如果想要图片在不同浏览器尺寸下保持同样比例的话:
<div class="relative pb-2/3">
<img class="absolute h-full w-full object-cover">
</div> 上面的pb-2/3是为了保持整个父容器的比例为一个矩形