前端应用--工程化主题切换功能

随着各个应用平台和网站都开始支持深色模式,相较于传统的页面配色方案,深色模式具有较好的降噪性,也能让用户的眼睛看内容更加舒适。

那么对于前端开发来说,如何高效的支持深色模式呢?这里的高效指的是工程化、自动化方案,不需要在开发过程中hard coding。

PostCSS原理及相关插件能力

postcss是一款使用JavaScript编写的用于编译css的工具,具有良好的插件性,非常有利于开发者扩展。

原理: PostCSS接受一个css文件,并提供了插件机制,提供给开发者分析、修改css规则,具体实现方式是基于AST技术。

设计主题切换功能前端自动化方案,站在架构的角度来说,需要思考的点有:

  • 如何维护不同主题色值
  • 谁来维护不同主题色值
  • 研发和设计之间,如何保持不同主题色值的同步沟通;
  • 如何最小化前端工程师的开发量,不需要hard coding两份颜色数值;
  • 如何做到一键切换时的性能最优;
  • 如何配合JavaScript状态管理,同步主题切换的信号

基于以上考虑,以一个超链接为例,我们希望做到在开发时,编写这样的代码:

a {
	color: cc(GBK05A)
}

这样的代码,能直接支持两套(light/dark)主题模式,即在应用编译时,上述代码预期被编译为下面的代码

a{
	color: #646464;
}
html[data-theme='dark'] a {
	color: #808080;
}

我们看一下在编译时,构建环节发生了什么:

  • cc(GBK05A)这样的声明,被编译为#646464
  • cc是一个css function,而GBK05A是一组色值,分别包含了light和dark两种主题的颜色
  • 同时在HTML根节点,添加属性选择器data-theme='dark',并添加a标签color色值样式为#808080

我们设想,用户点击“切换主题”按钮时,首先通过**JavaScript将HTML根节点标签添加data-themedark的属性值,这时CSS选择器html[data-theme='dark'] a将起作用,实现了样式的切换。

那么如何在构建时完成CSS的样式编译转换呢?答案指向PostCSS

  • 首先编写一个名为postcss-theme-colors的postcss创建,实现上述编译过程
  • 维护一个色值,结合上例即:
GBK05A: [ BK05, BK06 ]
BK05:  '#808080'
BK06: '#999999'

postcss-theme-color需要:

  • 识别cc()方法;
  • 读取色值
  • 通过色值,对cc()方法求值,得到两种颜色,分别对应dark和light模式;
  • 原地编译css中颜色为light模式的色值
  • 同时 dark 模式色值写到html节点上
    为了将dark模式色值按照html[data-theme='dark']方式写到HTML节点上,我们使用了另外两个Postcss插件完成
  • PostCSS Nested
  • PostCSS Nesting

一个PostCSS就是一个Node.js模块,开发者调用postcss.plugin(源码链接postcss.plugin)工厂方法返回一个插件实体。
postcss插件编写模板:

var postcss = require('postcss')
module.exports = postcss.plugin('pluginname',function(opts){
	opts = opts || {}
	return function(css, result) {
	 	// Transform the css ast
	}
})

插件实体形如:

return {
    postcssPlugin: 'PLUGIN_NAME',
    /*
    Root (root, postcss) {
      // Transform CSS AST here
    }
    */
    /*
    Declaration (decl, postcss) {
      // The faster way to find Declaration node
    }
    */
    /*
    Declaration: {
      color: (decl, postcss) {
        // The fastest way find Declaration node if you know property name
      }
    }
    */
  }
}

在编写postcss插件时,我们可以直接使用postcss.plugin方法完成实际开发。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值