2018-02-05 14:44
实现主题配色的通常需求有:
var
实现两种方式:
:root
和某个公共元素容器上,通过切换容器的属性来切换变量对应的色值前者在服务器渲染的场景下不适用,后者的例子:
/* 定义颜色 */
:root {
--myColor: '#fff';
}
/* 利用公共元素,当它匹配了特定属性时,改变变量对应色值 */
html[data-theme='dark'] {
--myColor: '#000';
}
/* 引用颜色 */
.myComponent {
color: var(--myColor);
}
原生 var 的缺陷有两个:
不兼容部分浏览器(IE 11 和 Android 4)
无法对颜色进行调整:
有标准 color-mod 函数,但还未有浏览器实现(更希望浏览器能让开发者自行实现不被支持 API,类似于 w3c/css-houdini-drafts)
也无法提前编译(如使用 postcss-color-function),因为变量的值在编译时还未决定。如果把调整之后的值保存到变量,则需要将每一种重要或不重要的边框、阴影或渐变定义到变量(并且每主题一份),这会使变量表不断增长
利用 PostCSS 我们可以定制想要的 CSS API,像原生 var 一样引用颜色,再继续使用 color function 来调整颜色。
输入:
a {
color: cc(G01);
background-color: color(cc(G01) alpha(-8%));
}
输出:
a {
color: #eee;
background-color: rgba(238, 238, 238, 0.92);
}
html[data-theme='dark'] a {
color: #111;
background-color: rgba(17, 17, 17, 0.92);
}
配置颜色的例子,postcss.config.js
:
/* 为颜色命名 */
const colors = {
C01: '#eee',
C02: '#111',
}
/* 按主题分组 */
const groups = {
G01: ['C01', 'C02'],
}
module.exports = {
plugins: [require('postcss-theme-colors')({colors, groups})],
}
缺陷:
为每一份主题生成一份 CSS 文件,例如 bundle.light.css、bundle.dark.css。如要切换主题,改变 link 指向的 CSS 文件路径。
缺陷:对工具使用和引用有过多的要求,尤其是在跨项目引用组件库时会很麻烦(为每个组件生成多份 CSS 或需要将 CSS 配置成源码模式编译)。
PS,我们的配色迁移案例是:
PPS,两个额外的夜间适配技巧:
filter: brightness(0.7)
来降低亮度filter: invert(0.6) hue-rotate(180deg)
转换到当前文本的颜色(0.6 = 0x99/0xff
)