自定义配置tailwindcss
theme
前言
css原子化应该已经出来很久了,代表的有tailwindcss 还有Unocss,今天我们主要介绍一下tailwindcss的配置。
tailwindcss官网
在开始之前,需要安装一下插件Tailwind CSS IntelliSense
,用于代码提示
安装
# postcss 和 autoprefixer 可选
npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
初始化配置文件
npx tailwindcss init -p
配置文件
// tailwind.config.js
module.exports = {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
导入全局样式
// global.css
// 这里导入的是tailwindcss的默认样式和一些预设的样式,可以按照需求导入
@tailwind base;
@tailwind components;
@tailwind utilities;
配置文件详解
主要配置就这几个,当然还有其他配置项,可以阅读官网配置的文档进行一一配置
属性 | 类型 | 描述 |
---|---|---|
content | Array | 指定哪些文件需要被tailwindcss处理,默认是当前目录下的所有文件,可以指定具体的文件路径,也可以使用glob模式。 |
theme | Object | 配置tailwindcss的主题,可以扩展默认的主题,也可以覆盖默认的主题。 |
plugins | Array | 配置tailwindcss的插件,可以扩展默认的插件,也可以覆盖默认的插件。 |
prefix | String | 配置tailwindcss的类名前缀,默认是"tw-" |
important | Boolean | 配置tailwindcss的样式是否需要加important,默认是false。 |
创建 theme.extend
配置项目
其中要自定义配置theme
,可以根据官方的extend
配置项去配置自定义的样式,这里可以配置所有的样式,
/** @type {import('tailwindcss').Config} */
module.exports = {
theme: {
extend: {
screens: {
'3xl': '1600px', // Adds a new `3xl:` screen variant
},
fontFamily: {
display: 'Oswald, ui-serif', // Adds a new `font-display` class
},
opacity: {
'0': '0',
'20': '0.2',
'40': '0.4',
'60': '0.6',
'80': '0.8',
'100': '1',
}
}
}
}
但是如果要一个一个去配置,有点麻烦,举个例子吧,在项目中,我们的宽度都是自定义的,1 - 2000
不等,但是官方的配置里面,无法通过 w-2000
这样的方式去赋值,所以我这里采用extend
去加载所有需要的样式,这样在书写过程中都可以使用任何1 - 2000
内的宽度,其他属性亦是如此。
生成过程分两步
1, 确定属性
确定需要生成的属性,因为不是所有的属性都需要,我们要定义哪些属性是需要去生成的,例如:width,height,margin,padding等,这里给出我的属性
- key: 属性名
- max: 属性的最大值
- min: 属性的最小值
// tailwind.config.json
{
"tailWindAttrs": [
{
"key": "width",
"max": 2000,
"min": 2
},
{
"key": "maxWidth",
"max": 2000,
"min": 2
},
{
"key": "height",
"max": 2000,
"min": 2
},
{
"key": "maxHeight",
"max": 2000,
"min": 2
},
{
"key": "borderWidth",
"max": 100,
"min": 2
},
{
"key": "padding",
"max": 1000,
"min": 0
},
{
"key": "margin",
"max": 1000,
"min": 0
},
{
"key": "borderRadius",
"max": 200,
"min": 0
},
{
"key": "lineHeight",
"max": 100,
"min": 0
},
{
"key": "zIndex",
"max": 1000,
"min": 0
},
{
"key": "gap",
"max": 500,
"min": 0
}
]
}
2, 创建属性
根据属性,要生成对应的属性值,这里可以写一个脚本函数去生成就好了,无非就是循环生成所有的
key-value
,然后组装成一个对应的object
,下面是我的脚本函数
/**
* target {number} 要循环多少次,比如 1000,这里要根据 tailwind.config.json 中的 max 值来决定最终的循环次数,在一个循环里面生成所有的 key-value,避免多次循环
* tailWindAttrs {Record<string, Record<string, string>>} tailwind.config.json 中的tailWindAttrs属性
*/
const getAttrubutes = (target: number) => {
const obj: Record<string, Record<string, string>> = {}
// 最外层循环
for (let i = 0; i < target; i++) {
// 内层循环,根据tailWindAttrs里面的属性个数,循环生成对应的key-value
for (let index = 0; index < tailWindAttrs.length; index++) {
const cur = tailWindAttrs[index]
if (cur.max > i) {
if (obj[cur.key]) {
obj[cur.key] = {
...obj[cur.key],
[i]: i + 'px',
}
} else {
obj[cur.key] = {
[i]: i + 'px',
}
}
}
continue
}
}
return obj
}
3,使用
import Colors from 'tailwindcss/colors'
import type { Config } from 'tailwindcss'
const attributes = getAttrubutes(2000)
export default {
content: [
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
'./app/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {
...attributes,
colors: {
...Colors,
...themeColor,
},
},
},
plugins: [],
} satisfies Config
到这里就完成了,如果需要更多的属性,只需要在tailWindAttrs
数组里面添加对应的属性即可。
4,优化
上面的代码虽然实现了功能,但是每次都需要重新生成所有的属性,每次都需要遍历,这样会导致每次启动项目都会重新生成,这样显然是不合理的,所以我们需要优化一下。
我们可以将生成的属性保存到本地,然后在项目启动的时候读取本地文件,如果本地文件不存在,则重新生成并保存到本地。
创建一个脚本去生成属性,并保存到本地
// tailwindcss.config.ts
import chalk from 'chalk'
import fs from 'node:fs'
import path from 'node:path'
// 导入之前配置的属性
import { tailWindAttrs } from '../theme/tailwind.config.json'
// 要缓存的目标地址:把生成的属性保存到cache下面的tailwindcss目录下面
const CACHE_PATH = '../.cache/tailwindcss'
// 缓存文件名
const FILE_NAME = 'tailwind.tmp.json'
// 缓存的完整路径 ../.cache/tailwindcss/tailwind.tmp.json
const FULL_PATH = path.join(CACHE_PATH, FILE_NAME)
/**
* 判断缓存是否存在
*/
const isCache = () => {
const tmp = path.resolve(__dirname, CACHE_PATH, FILE_NAME)
if (fs.existsSync(tmp)) {
return true
}
return false
}
/**
* 获取缓存
*/
const getCache = () => {
return JSON.parse(fs.readFileSync(path.resolve(__dirname, FULL_PATH), 'utf-8'))
}
/**
* 生成属性
*/
const getAttrubutes = (target: number) => {
const obj: Record<string, Record<string, string>> = {}
for (let i = 0; i < target; i++) {
for (let index = 0; index < tailWindAttrs.length; index++) {
const cur = tailWindAttrs[index]
if (cur.max > i) {
if (obj[cur.key]) {
obj[cur.key] = {
...obj[cur.key],
[i]: i + 'px',
}
} else {
obj[cur.key] = {
[i]: i + 'px',
}
}
}
continue
}
}
return obj
}
/**
* 设置缓存,生成属性之后,将属性写入缓存文件
*/
const setCache = () => {
const now = new Date().getTime()
console.log(chalk.yellow('[ tailwindcss ] no cached, now is generate attrubutes, please wait ...\n'))
const result = getAttrubutes(2000)
const cur = new Date().getTime()
console.log(chalk.cyan(`[ tailwindcss ] attrubutes is created, Total time spent ${(cur - now) / 1000}s \n`))
// 将result写入到cache文件目录下
fs.mkdirSync(path.resolve(__dirname, CACHE_PATH), { recursive: true })
fs.writeFileSync(path.resolve(__dirname, FULL_PATH), JSON.stringify(result), {
encoding: 'utf-8',
})
const ctm = new Date().getTime()
console.log(
chalk.green(`[ tailwindcss ] is write ${FILE_NAME} in ${FULL_PATH}, Total time spent ${(ctm - now) / 1000}s\n`)
)
return result
}
/**
* 入口函数,有缓存直接读取缓存,没有缓存则生成属性
*/
export const init = () => {
if (isCache()) {
console.log(chalk.green('[ tailwindcss ] is cached 🎉, now is using cache file. \n'))
return getCache()
}
return setCache()
}
export const themeExtend = init()
到这里,基本就全部完成了,这里可以根据需要去决定是否要这样做,如果觉得麻烦,也可以直接使用 tailwindcss
的默认配置,但是这样生成的属性就会比较少。大家可自己权衡决断