Tailwindcss 的本质是一个 Node.JS 的应用,通过配置项来生成我们所需要的 CSS 类,使得我们不需要使用写 CSS 就能快速的快速的布局。要使用 Tailwindcss 需要的就是搞明白 Tailwindcss 应该如何配置,如果需要用到小程序中,就需要知晓小程序的类不同与浏览器的类。
原本以为写了 Tailwindcss 是不会有人关注的,后来还是有人关注了 tailwindcss ,这里就把出现的问题尽量的说明白和补齐。但是还是不推荐将其运用在生产环境,因为并没有大量的实践, 愿意国内探究 tailwindcss 人并不多, CSS 似乎也不被人很重视。同时推荐使用 vscode 进行代码编写。下面介绍关于 tailwindcss 的插件支持。
- 插件1:Tailwind CSS IntelliSensePreview 用于智能感知
- 插件2:headwind 用于排序
- 插件3:Tailwind CSS Autocomplete for Visual Studio Code
目标:(目前主要目标是小程序,因为官方网站缺失关于小程序方面使用)
- 在原生小程序中使用 tailwindcss
- 在 mpvue 中使用 tailwindcss
- 在 uni-app 中使用 tailwindcss
- 在 taro-react/taro-vue 中使用 tailwindcss
当然也可以探索更多:
- React 当中如何使用 Tailwindcss
- Vue 中如何使用 Tailwindcss
- Angular 中如何使用 Tailwindcss
- Svelte 中使用 Tailwindcss
Tailwindcss 与原生小程序
原生的小程序推荐是 gulp 来构建微信小程序,gulp 简单容易配置。我们使用小程序提供的命令行工具来创建小程序项目,主要依赖如下
- gulp/gulp-postcss
- @wechat-miniprogram/miniprogram-cli 生成小程序项目
- tailwindcss
# 项目创建命令行
yarn global add @wechat-miniprogram/miniprogram-cli --dev
# 构建工具
yarn add gulp gulp-postcss --dev
# 主依赖
yarn add tailwindcss
Gulp 打包
// gulp 配置
初始化 tailwindcss 基本配置
安装完成之后,就可以使用 tailwindcss 的命令行工具tailwindcss进行初始化了。
- 生成 tailwindcss.config.js 配置文件
- 注入tailwindcss 指令,指令如下
@tailwind base; // 实际就是 normalize.css 在小程序中用不上,需要忽略不使用
@tailwind components; // 组件类
@tailwind utilities; // 工具类
注意:
-
类规范:使用之后发现,tailwindcss 默认的配置的生成的 css 代码中,有很大一部分是不符而小程序的 class "规范" (小程序中 class 仅仅支持中划线
-和下划线_)的,他们集中的表现在 Pseudo-Class Variants, 但是小程序中,我们能够使用伪类是有限制的,或者我们可以将默认的编译 Variants 配置项全部清空(目的是不生成 Variants 的 css 代码),如果有需要直接写我们自己需要 Variants来解决问题。 -
不适用与小程序环境的css特性。在小程序环境中响应式布局也基本上用不上,此时,我们在配置文件中去掉这两项之后,发现原来几万行的代码,只有几千行了,一个类,基本上要占据三行,所以实际的css属性,应该就是及千行的样子。
-
单位和负值的处理。就是 tailwindcss 在计算 负值 的时候,识别的单位是 web 端的单位,不能识别 rpx, 所以我们需要负的 margin 的时候,我们就需 要自己处理这个负值的情况,以便适用于小程序。毕竟 tailwindcss 是老外搞出来的东西,国外可没有微信小程序,负值就需要自己来写函数来生成对应的负值。
体验
体验这一部分,自己的做了一个简单名片的例子,然后发现问题:单位是 rem, 小程序使用的rpx作为单位,我们就想着自己来配置大小和单位的事情,跟这官方网站自己摸索如何写css, 如何布局。说道这里,如果我们想要学习 tailwindcss,学会写插件,学会写工具类。有能力改写配置,才能灵活的运用
关于小程序公共部分
const cloneDeep = require('lodash/cloneDeep')
const defaultConfig = require('./stubs/defaultConfig.stub.js')
module.exports = cloneDeep(defaultConfig.theme)
自定义主题 theme
关于:官方的 theme,下面是我们简单的配置 tailwindcss theme。 有如下的点要注意:
- 单位,使用 rpx(单位的使用要根据具体的情况开使用)
- 添加百分比(宽度,高度等等...)
- 添加渐变(使用插件添加渐变能力)
// tailwind.config.js
module.exports = {
theme: {
screens: {},
spacing: {
px: '1px',
'0': '0',
'1': '1rpx',
'2': '2rpx',
'4': '2rpx',
'6': '6rpx',
'8': '8rpx',
'10': '10rpx',
'12': '12rpx',
'14': '14rpx',
'16': '16rpx',
'18': '18rpx',
'20': '20rpx',
'22': '22rpx',
'24': '24rpx',
'26': '26rpx',
'28': '28rpx',
'30': '30rpx',
'32': '32rpx',
'34': '34rpx',
'36': '36rpx',
'38': '38rpx',
'40': '40rpx',
'42': '42rpx',
'44': '44rpx',
'46': '46rpx',
'48': '48rpx',
'50': '50rpx',
'60': '60rpx',
'56': '56rpx',
'64': '64rpx',
'70': '70rpx',
'80': '80rpx',
'90': '90rpx',
'100': '100rpx',
'120': '120rpx',
'140': '140rpx',
'160': '160rpx',
'200': '200rpx',
'260': '260rpx',
'300': '300rpx',
'350': '350rpx',
'400': '400rpx',
'500': '500rpx',
'600': '600rpx',
'700': '700rpx',
'750': '750rpx'
},
// 还有特殊的我们就添加特定
width: theme => ({
auto: 'auto',
...theme('spacing'),
'1_5': '20%',
'2_5': '40%',
'3_5': '60%',
'4_5': '80%',
'5_6': '83.333333%',
'1_12': '8.333333%',
'2_12': '16.666667%',
'3_12': '25%',
'4_12': '33.333333%',
'5_12': '41.666667%',
'6_12': '50%',
'7_12': '58.333333%',
'8_12': '66.666667%',
'9_12': '75%',
'10_12': '83.333333%',
'11_12': '91.666667%',
full: '100%',
screen: '100vw'
}),
height: theme => ({
auto: 'auto',
...theme('spacing'),
full: '100%',
screen: '100vh'
}),
inset: {
'20': '20rpx',
'-20': '-20rpx',
'-10': '-10rpx'
},
margin: (theme, { negative }) => {
// 使用了 reduce 这个包 rpx 是能转换的暂时自己比变量添加
return {
auto: 'auto',
...theme('spacing'),
...myNegative(theme('spacing'))
}
},
letterSpacing: {
tighter: '-1px',
tight: '-0.5px',
normal: '0',
wide: '1rpx',
wider: '2rpx',
widest: '3rpx'
},
fontSize: {
xs: '12rpx',
sm: '14rpx',
base: '16rpx',
lg: '18rpx',
xl: '20rpx',
'2xl': '24rpx',
'3xl': '30rpx',
'4xl': '36rpx',
'5xl': '48rpx',
'6xl': '64rpx'
},
gradients: theme => ({
// blue to other
'blue-green': [theme('colors.blue.500'), theme('colors.green.500')],
'blue-purple': [theme('colors.blue.500'), theme('colors.purple.500')],
// green to other
'green-blue': [theme('colors.green.500'), theme('colors.blue.500')],
'green-red': [theme('colors.green.500'), theme('colors.red.500')],
// purple to other
'purple-blue': [theme('colors.purple.500'), theme('colors.blue.500')],
'purple-orange': [theme('colors.purple.500'), theme('colors.orange.500')],
'purple-yellow': [theme('colors.purple.500'), theme('colors.yellow.500')],
// orange to other
'orange-purple': [theme('colors.orange.500'), theme('colors.purple.500')],
'orange-indigo': [theme('colors.orange.500'), theme('colors.indigo.500')],
// red to other
'red-purple': [theme('colors.red.500'), theme('colors.purple.500')],
'red-green': [theme('colors.red.500'), theme('colors.green.500')],
// teal to other
'teal-red': [theme('colors.teal.500'), theme('colors.red.500')],
// indigo to other
'indigo-red': [theme('colors.indigo.500'), theme('colors.red.500')],
// pink to other
'pink-red': [theme('colors.pink.500'), theme('colors.red.500')],
'pink-blue': [theme('colors.pink.500'), theme('colors.blue.500')],
// yellow to other
'yellow-indigo': [theme('colors.yellow.500'), theme('colors.indigo.500')]
}),
extend: {
boxShadow: {
// display: '-3rpx -3rpx 10rpx 2rpx rgba(0,0,0,.3) inset, 0 0 0 6rpx rgba(255, 255, 255, .6) inset, 0 0 0 1rpx rgba(0,0,0,.5), 2rpx 2rpx 10rpx rgba(0,0,0,.6)'
display: '-3rpx -3rpx 10rpx 2rpx rgba(0,0,0,.3) inset, 0 0 0 14rpx rgba(255, 255, 255, .6) inset, 0 0 0 1rpx rgba(0,0,0,.5), 2rpx 2rpx 10rpx rgba(0,0,0,.6)'
}
}
},
}
// 处理负值
function myNegative (obj) {
let __obj = {}
// 负值转换
for (let key in obj) {
if (key === 0 || key === '0') {
__obj[`${key}`] = `${obj[key]}`
} else {
__obj[`-${key}`] = `-${obj[key]}`
}
}
return __obj
}
主题 theme 本质就是 css 特性,使用 JavaScript 进行描述,Node.JS 根据配置生成 css。如有其他的配置项,按照自己的需求配置即可。
Tailwindcss 变异 Variants
module.exports = {
// 置空 variants,所有的 编译都不使用
variants: [],
}
插件
参考:编写 Tailwindcss 插件,下面是以插件的方式实现了:
- 文本背景颜色(类名:text-clip)
- 首字母大写 (类名:inital-capitalize:first-letter)
- 字体方法 (类名:vertical-lr)
- 多行的折叠 + 省略号 (类名:truncate-2/3/4)
// 插件
module.exports = function (options) {
return function ({ addUtilities }) {
addUtilities({
// 文本背景颜色
'.text-clip': {
backgroundClip: 'text',
'-webkitBackgroundClip': 'text',
color: 'transparent'
},
// 首字母大写
'.inital-capitalize:first-letter': {
fontSize: '50rpx'
},
// 字体的垂直方向
'.vertical-lr': {
'writing-mode': 'vertical-lr' /* 从左向右 从右向左是 writing-mode: vertical-rl; */
// 'writing-mode': 'tb-lr' /* IE浏览器的从左向右 从右向左是 writing-mode: tb-rl; */
},
// 多行的折叠 + 省略号 + 注意是 -webkit 内核使用
'.truncate-2': {
overflow: 'hidden',
/* text-overflow: ellipsis; 有些示例里需要定义该属性,实际可省略 */
'display': '-webkit-box',
'-webkit-line-clamp': '2',
'-webkit-box-orient': 'vertical'
},
'.truncate-3': {
overflow: 'hidden',
'text-overflow': 'ellipsis', /* 有些示例里需要定义该属性,实际可省略 */
'display': '-webkit-box',
'-webkit-line-clamp': '3',
'-webkit-box-orient': 'vertical'
},
'.truncate-4': {
overflow: 'hidden',
'text-overflow': 'ellipsis', /* 有些示例里需要定义该属性,实际可省略 */
'display': '-webkit-box',
'-webkit-line-clamp': '4',
'-webkit-box-orient': 'vertical'
}
})
}
}
插件2:使用插件实现渐变功能 gradients
const _ = require('lodash')
module.exports = function ({ addUtilities, e, theme, variants }) {
const gradients = theme('gradients', {})
const gradientVariants = variants('gradients', [])
const utilities = _.map(gradients, ([start, end], name) => ({
[`.bg-gradient-${e(name)}`]: {
backgroundImage: `linear-gradient(to right, ${start}, ${end})`
},
[`.bg-gradient-bottom-${e(name)}`]: {
backgroundImage: `linear-gradient(to bottom, ${start}, ${end})`
}
}))
addUtilities(utilities, gradientVariants)
}
配置项中加载插件:
module.exports = {
plugins: [
require('./plugins/base')(),
require('./plugins/gradients')
],
}
处理负值
下面是处理负值的情况,为什么要处理负值,原因在于 Tailwindcss 源码中单位,没有对 rpx 的支持,所以当我们使用的时候负值也是需要单独处理的,下面是一个简单的负值的处理函数:
function myNegative(obj) {
let __obj = {}
// 负值转换
for (let key in obj) {
if (key === 0 || key === '0') {
__obj[`${key}`] = `${obj[key]}`
} else {
__obj[`-${key}`] = `-${obj[key]}`
}
}
return __obj
}
Mpvue 与 Tailwindcss
- 安装和初始化 mpvue 项目
# 全局安装 vue-cli
$ npm install --global vue-cli
# 创建一个基于 mpvue-quickstart 模板的新项目
$ vue init mpvue/mpvue-quickstart tailwindcss-app
# 安装依赖
$ cd tailwindcss-app
$ npm install
# 启动构建
$ npm run dev
- 配置 postcss
// https://github.com/michael-ciniawsky/postcss-load-config
const purgecss = require('@fullhuman/postcss-purgecss')
module.exports = {
plugins: [
require('postcss-import'),
require('tailwindcss'),
require('autoprefixer')({grid: false}),
// purgecss({
// content: ['./**/*.vue']
// }),
require('postcss-mpvue-wxss')
]
}
- 添加指令
<style lang="scss">
@import './styles/aminate.css';
@import './icons.scss';
@import './styles/layout';
@tailwind utilities;
page {
font-family: PingFang SC, 'Helvetica Neue', Arial, sans-serif;
}
view {
box-sizing: border-box;
font-family: PingFang SC, 'Helvetica Neue', Arial, sans-serif;
}
.container {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
padding: 200rpx 0;
box-sizing: border-box;
}
</style>
打包之后,会生成 dist/wx 目录,可以在该目录中查看tailwindcss生成的 CSS 类。
- 删繁就简 tree-shaking
控制大小,tailwindcss 是机器生成代码,没有使用到的代码还有很多,Tailwindcss 官方也提供了方案:purgecss。
Taro 与 Tailwindcss
Taro Next 中也有了对 Vue 的支持,但是 Taro 不一样的是 Taro 有自己的配置文件,Postcss 文件就能够自定义,我们就只能使用最原始的方式来定义.
- 初始化一个 Taro 项目
# 安装 taro
# yarn add @taro/cli
taro init tailwindcss-taro-app
- 添加 tailwindcss 配置
如上 mpvue 的配置即可,仅仅是作为示例,说明问题即可。
- 添加postcss配置
由于 taro 有自己专有的配置文件,位于 config 文件夹下面,官方配置postcss插件只是提供几种,我们需要自己将tailwindcss插件添加到其中:
// config/dev.js
module.exports = {
env: {
NODE_ENV: '"development"'
},
defineConstants: {},
mini: {
postcss: {
tailwindcss: {
enable: true,
}
}
},
h5: {}
}
- 运行
使用 taro 提供的命令进行打包编译即可。
Uni-app 与 Tailwindcss
- 使用命令行初始化一个 uni-app 项目
vue create -p dcloudio/uni-preset-vue tailwindcss-app
- 添加 tailwindcss
# 进入工作目录
cd tailwindcss-app
# 添加 tailwincss 支持
yarn add tailwindcss
# 使用 tailwind 命令初始化配置文件
tailwind init # 默认生成 tailwind.config.js
tailwindcss 配置文件,根据自己的实际情况而定,也可参考上面关于建议
- 配置 postcss
// postcss.config.js
module.exports = {
parser: require('postcss-comment'),
plugins: [
// ...
require('tailwindcss'),
require('autoprefixer')({
remove: process.env.UNI_PLATFORM !== 'h5'
})
// ...
]
}
- 添加指令
默认的uni-app项目使用 scss css 预处理器,我们可以在合适地方,如全局的css入口使用@tailwind指令生成配置的 css 代码。例如在 App.vue 中注入指令:
<style lang="scss">
/*每个页面公共css */
@tailwind utilities;
</style>
编译之后,对应的代码就会打包到 dist/dev/mp-weixin/common/main.wxss 中。
- vscode 插件
vscode 插件支持智能感知,vscode 可能不能及时生效,可以重新启动 vscode, 即可。
- 删繁就简
控制大小,tailwindcss 是机器生成代码,没有使用到的代码还有很多,Tailwindcss 官方也提供了方案:purgecss。
// tailwind.config.js
module.exports = {
purge: [
'./src/**/*.html',
'./src/**/*.vue',
'./src/**/*.jsx',
],
}
后面
tailwindcss 是一个快速的构建布局样式的css框架,基于postcss, 在原子css的思想上,提供了可配置,插件化的增强 ACSS 的能力。是天生响应式。
解析来要做的事情
- [ x ] Tailwindcss 源码分析,更加深入的理解 tailwindcss。
- [ x ] 分析源码,修正文章