当前位置:   article > 正文

前端应用--工程化主题切换功能_html[data-theme=dark]

html[data-theme=dark]

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

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

PostCSS原理及相关插件能力

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

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

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

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

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

a {
	color: cc(GBK05A)
}
  • 1
  • 2
  • 3

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

a{
	color: #646464;
}
html[data-theme='dark'] a {
	color: #808080;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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

  • 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'
  • 1
  • 2
  • 3

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
	}
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

插件实体形如:

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
      }
    }
    */
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/332305
推荐阅读
相关标签
  

闽ICP备14008679号