组件仍在补充, 欢迎加群交流哦,微信: a2298613245
headless ui
✕
组件还在补充中,希望能够帮助你有一个亮点项目放入简历!
全局方案
按钮 Button
图标 Icon
布局 Grid
间距 Space
输入框 Input
弹窗 Modal
弹出框 Popover
消息 Toast
警告 Alert
单选框 Radio
复选框 Checkbox
标签 Tag
其它组件
换肤方案
CSS 换肤方案
Tailwind 换肤方案
Next.js 换肤方案

Tailwindcss 换肤方案

孟祥_成都 🔥前端技术专家,全栈开发工程师
button

介绍

上篇文章讲了 css 的主题色方案,其实 Tailwindcss 也可以通过 css 变量来实现。原理几乎是一样的,这里我们使用的 Tailwindcss 版本是 3.x, 主要原因是 4.x 版本所支持的浏览器太新了,在国内很容易引起不兼容的问题。但本质上还是借助 css 变量实现换肤,懂得原理后,跟版本没什么太大关系。

请从上面 CSS 换肤方案 了解 css 变量换肤方案 的具体实现。这里就不赘述了。实现思路主要分为两层:

1、局部样式改变

比如所有的 button 默认都是蓝色,但是某个 button 我想是黄色,允许单独给 button 传递主题色。

2、全局样式改变

比如我想对所有的 button 的主色都设为绿色,提供一个全局更换颜色配置的入口。

实现

1. 定义 css 变量

首先我们抽象的业务颜色会放在 tailwind.config.ts(这是 tailwindcss 3.x 版本的配置文件,4.x 版本貌似被移除了),以下是一个简单的示例, 包含对业务颜色的定义,以及 border 颜色的定义,当然你可以根据自己的业务需要,跟 ui 同学对齐所有变量。

1import type { Config } from 'tailwindcss'; 2 3export default { 4content: ['./pages/**/*.{js,ts,jsx,tsx,mdx}', './components/**/*.{js,ts,jsx,tsx,mdx}', './app/**/*.{js,ts,jsx,tsx,mdx}'], 5theme: { 6 extend: { 7 borderColor: () => ({ 8 color: 'var(--border-color)', 9 'color-50': 'var(--border-color-50)', 10 'color-100': 'var(--border-color-100)', 11 'color-200': 'var(--border-color-200)', 12 'color-800': 'var(--border-color-800)', 13 }), 14 colors: () => ({ 15 primary: { 16 color: 'var(--primary-color-blue-600)', 17 hover: 'var(--primary-color-blue-500)', 18 focus: 'var(--primary-color-blue-200)', 19 active: 'var(--primary-color-blue-700)', 20 disabled: 'var(--primary-color-blue-300)', 21 }, 22 warning: {//...}, 23 error: {//...}, 24 success: {//...}, 25 }), 26 }, 27}, 28plugins: [], 29}

我们的可以看到,其中颜色,例如 primary 也就是网站品牌的主色调,我分为了

  • color:常规色
  • hover: hover 态颜色
  • focus:聚焦颜色
  • active:激活态颜色
  • disabled:禁用态颜色

2. 全局样式改变

其中 css 变量的引入,可以在项目入口文件,例如 App.tsx,引入 css 变量。

例如我们在 html 定义一个自定义属性 class,值为 light 或者 dark。

1html.light { 2 --primary-blue-600: #366ef4; 3 --primary-blue-500: #2557e7; 4 --primary-blue-200: #c3dafe; 5 --primary-blue-700: #204ed6; 6 --primary-blue-300: #93c5fd; 7 /* .... */ 8}

同时,初始化的时候,我们在 html 标签中添加 class 属性,值为 light 或者 dark,这样我们就可以根据 class 的值,来切换主题。

1<html class="light"></html>

一般情况,切换主初始化还需要把当前的主题的值存到 localStorage 里面。因为 SPA 页面初始化 html 是没有内容的,所以是可以在框架里,例如 React 中渲染初始化获取到 localStorage 的值,赋予 html 相应的 class 属性。

3. 局部样式改变

局部样式改变很简单,利用 css 的优先级机制即可。我们来举一个例子:

看这一段 HTML:

1<div class="one"> 2<div class="two"> 3 <div class="three"></div> 4 <div class="four"></div> 5</div> 6</div>

配套的 CSS:

1.two { 2 --test: 10px; 3} 4.three { 5 --test: 2em; 6}

在这个情况下, var(--test) 的结果分别是:

对于元素 class="two" :10px 对于元素 class="three" :2em 对于元素 class="four" :10px (继承自父属性) 啥意思呢,就是我的 button 组件,我可以默认用全局变量的样式,比如我设置在 body 上,然后 button 组件包裹一个 div, div 上也有同名的一个变量,那么 button 组件会优先使用 div 上的变量。

基于以上原理我可以在 button 组件里,直接在 style 中用来设置 css 变量,代码如下

1const localBtnTheme = { 2 "--btn-color": "red", 3 "--btn-width": 12 4}; 5 6<div style={{ style, ...localBtnTheme }} >

其中 style 是正常外面传给组件的 style, localBtnTheme 是指 css 变量。所以我们只需要使用跟全局变量定义一样的 css 变量,就可以覆盖全局的样式。

介绍
实现
1. 定义 css 变量
2. 全局样式改变
3. 局部样式改变