ant社区全球论坛什么意思,ant社区是做什么的

  

     

  

  多主题介绍自从IOS 13.0支持DarkMode后,多主题逐渐流行起来,用户可以手动或自动切换到自己喜欢的主题颜色。本文详细介绍了如何在前端页面实现多主题改编。   

  

  Mac系统支持的明暗主题示意图:   

  

     

  

  在实施多主题方案之前,我们应该首先了解两个问题。   

  

  为什么会有深色图案?   

  

  在视力正常(或矫正视力)的人群中,浅色模式的视觉表现往往更好,而一些患有白内障及相关疾病的人群在深色模式下可能表现更好。另一方面,长时间在光线模式下阅读可能与近视有关。对于日常生活中需要长时间使用的应用,深色模式会减轻眼睛疲劳。我应该实现黑暗题材的改编吗?   

  

  根据相关研究调查数据,它超过了80%(在Mac上,而不是iOS上,但这给出了一个趋势)。虽然这个数字可能被高估了,但说明有很大比例的人在用。所以对于使用黑暗模式的用户来说,切换到不支持的应用确实很不舒服,他们很可能会为此删除应用或关闭页面。   

  

  多主题已经成为改善用户体验的基本手段,现代前端应该支持这种场景。接下来,我们将深入解释如何在WEB场景中适应多主题。   

  

  多主题技术方案探索   

  

  浏览器支持基于操作系统的明暗风格,但前端页面的多主题需要开发者具体开发才能实现主题切换。   

  

  操作系统支持在具体实现之前,先了解系统支持级别对黑暗模式的支持:   

  

  macOS 10.14引入了黑暗模式。ios13在2019年3月发布的ios13版本加入了dark modeAndroid 10(API level 29)以及之后的版本提供了黑暗主题背景window102018年10月10日,在现代设备中,系统层同时支持暗主题和亮主题,所以无论是新项目还是运行多年的老项目都应该这么做。   

  

  自定义风格改编创意页面基本上通过自定义风格UI库呈现整体愿景。先说自定义样式:自定义样式使用CSS变量控制多个主题(CSS变量的基本用法这里不再赘述。介绍请参考阮一峰写的CSS变量教程)   

  

  !- html节点添加主题自定义属性-htmldata-theme=' light '!-使用CSS变量控制style-body style=' background 3360 var(-body-background)'/body/html//将与主题无关的变量放入root 3360 root {-border-radius-base 33606 px;}//对于主题相关的变量,通过属性选择器html 3360 root {-body-background 3360 # efeef增加优先级;} html : root {-body-background : # 000;}UI库适配思路开源社区提供的流行UI库主题适配方案是通过CSS变量。但是,由于CSS变量的最新规范,不支持较旧的项目。Vue的Element UI和React的Ant Design是两个社区开发比较好的UI库。因为比较老的项目,两个都不支持CSS可变主题方案。   

  

  以Ant Design为例,多主题的内部实现是通过定义less变量,使得主题无法动态切换(下面将具体讨论主题的动态切换)。   

  

  Ant Design目前正致力于支持所有组件的CSS变量。详细进度请参考这里。   

  

  但是,做改编工作不能等官方支持,需求不等人。以antd为例,分别构建不同的主题样式,通过添加属性选择器前缀来控制antd样式的优先级,可以实现适配明暗主题。   

  

  html-theme=' light '/html html . ant-button { color 3360 # fff } html . ant-button { color 3360 # 000 }动态切换主题的思路页面切换主题需要从以下三个维度来考虑:   

p>   

系统主题更换页面提供主题切换按钮,用户主动切换通过URL控制当前主题切换主题的核心思路是通过控制CSS变量,在不同主题下显示不同的样式。

  

系统主题切换

  

浏览器暴露主题切换接口:

  

CSS

  

媒体查询 @media(prefers-color-scheme: dark)

  

JavaScript

  

window.matchMedia("(prefers-color-scheme: dark)")

  

api支持程度:

  

  

通过CSS媒体查询控制CSS变量:

  

body { background: var(--body-background); transition: background 0.3s;}@media (prefers-color-scheme: light) { :root { --body-background: #efefef; --text-color: #333; }}@media (prefers-color-scheme: dark) { :root { --body-background: #000; --text-color: #ededed; }}优点是实现简单,识别交给浏览器去做,简单页面直接使用这个方案即可。

  

缺点是不利于扩展,后续支持用户主动切换主题比较乏力,所以我们下面按照属性选择器加CSS变量实现控制。

  

通过JS暴露接口:

  

通过JS识别当前系统主题,对于CSS变量的控制不应该使用JS去写,因为当主题色多的话,需要对每个属性都执行这行代码:

  

document.documentElement.style.setProperty('--theme-color', '#YOURCOLOR');JS控制CSS变量不利于后续扩展。

  

较合适的方案是上面提到的:通过属性选择器控制根节点CSS变量

  

/* 浅色模式 */html:root { --body-background: #efefef; --text-color: #333;}/* 深色模式 */html:root { --body-background: #000; --text-color: #ededed;}JS通过识别系统主题,设置页面主题标识

  

// 给HTML DOM节点添加自定义主题,标识当前主题const toggleTheme = (isDarkMode) => { htmlEl.setAttribute("data-theme", isDarkMode ? "dark" : "light");};const themeMedia = window.matchMedia("(prefers-color-scheme: dark)");// 页面初始化切换toggleTheme(themeMedia.matches);// 监听系统切换themeMedia.addListener((e) => { toggleTheme(e.matches);}); 页面提供切换按钮,用户主动切换

  

需要在html节点添加自定义属性,并根据当前主题色通过CSS变量控制。

  

点击切换按钮后设置自定义属性值即可。

  

/* 浅色模式 */html:root { --body-background: #efefef;}/* 深色模式 */html:root { --body-background: #000;}body { background: var(--body-background); transition: background 0.3s;}const htmlEl = document.documentElement;const buttonEl = document.getElementById("btn");buttonEl.addEventListener("click", () => { const currentTheme = htmlEl.getAttribute("data-theme"); const nextTheme = currentTheme === "dark" ? "light" : "dark"; htmlEl.setAttribute("data-theme", nextTheme);}); 通过URL控制当前主题

  

页面加载后根据URL query参数动态添加到html节点自定义属性,并根据当前主题色通过CSS变量控制。

  

const search = new URLSearchParams(location.search);const theme = search.get("theme") || "light";document.documentElement.setAttribute("data-theme", theme);上面三种场景结合起来,基本满足目前多主题所有需求。

  

在线DEMO: codesandbox.io/s/multiple-…

  

多主题方案实现如果项目中没有使用UI库或使用了支持CSS变量主题适配的UI库,可以本章内容,请直接参考上面技术方案探索。

  

根据上面「多主题技术方案探索」结论,我们从「UI库适配」和「自定义样式适配」来介绍下页面如何从0到1实现多主题适配。

  

先放一张最终实现效果图,源码已放到 github 仓库,有条件的看官可以边看源码,边阅读下面的示例代码

  

  


  

UI库主题适配实现基于Ant Design具体讲UI库如何实现多主题方案。对于其他不支持的UI库(Element UI等等),实现的思路大致相同。

  

共分为三个步骤:

  

配置多主题样式重写组件样式构建样式文件通过配置深色和浅色两套主题文件,分别对需要自定义样式的less变量赋值。最终构建两套主题样式,分别加上属性选择器前缀。

  

# 文件目录结构.├── src│ └── theme│ ├── antd.css # 构建产物│ ├── antd.custom.variable.less # 自定义antd less变量│ ├── antd.dark.base.less # 自定义 antd 深色主题│ ├── antd.light.base.less # 自定义 antd 浅色主题│ ├── antd.less # 构建入口文件└── theme.sh构建两套样式无疑增加了构建产物大小,最终构建两套样式文件大小约为1.4M,gzip后300K左右。

  

如果你的项目是刚启动并且比较小,可以使用支持CSS变量的UI库。

  

如果项目预期会很庞大,而且希望使用antd周边生态比较完善的库,那么我建议你做这件事情。

  

配置多主题样式

  

antd.custom.variable.less 自定义antd less变量文件

  

为什么要单独设置一份antd的less变量设置,由于上面提到过的:antd作为老项目基本都支持CSS变量,主题方案是通过less变量实现的,所以我们要自己设置不同主题的less变量。

  

@live-primary-color: #ff0040;// default@live-body-background: #efefef;@live-text-color: #666;// dark@live-body-background-dark: #000;@live-text-color-dark: #bfbfbf;antd.dark.base.less 自定义 antd 深色主题

  

@import './antd.custom.variable.less';@import '../../node_modules/antd/lib/style/themes/dark.less';@import '../../node_modules/antd/dist/antd.less';// 覆盖antd less变量值@primary-color: @live-primary-color;@body-background: @live-body-background-dark;antd.light.base.less 自定义 antd 浅色主题

  

@import "./antd.custom.variable.less";@import "../../node_modules/antd/lib/style/themes/default.less";@import "../../node_modules/antd/dist/antd.less";// 覆盖antd less变量值@primary-color: @live-primary-color;@body-background: @live-body-background;构建:分别构建浅色和深色主题

  

# '编译暗黑主题样式'npx lessc --js ./src/theme/antd.dark.base.less ./src/theme/antd.dark.base.css# '编译白色主题样式'npx lessc --js ./src/theme/antd.default.base.less ./src/theme/antd.default.base.css构建产物:antd.dark.base.css antd.default.base.css

  

自定义UI库样式

  

variable.css 自定义CSS变量

  

此文件用于自定义样式和UI库样式的CSS变量合集

  

:root { --live-primary-color: #ff0040; --live-font-size-base: 14px; --live-font-size-lg: 16px; --live-font-size-sm: 12px;}html:root { --live-body-background: #efefef;}html:root { --live-body-background: #000;}ant.less 自定义UI库样式文件

  

@import (less) "./variable.css";html { @import (less) "./antd.default.base.css";}html { @import (less) "./antd.dark.base.css";}html,html { .ant-btn { font-size: var(--font-size-lg); &-lg { font-size: 18px; } &-sm { font-size: var(--font-size-base); } }}构建:给浅色和深色分别添加作用域,并加入自定义UI样式。

  

因为我们整体的切换主题要结合html标签的自定义属性 data-theme 的值为 light 或 dark 来实现,所以要结合构建的浅色和深色的的两份主题文件添加作用域。

  

npx lessc --js -clean-css ./src/theme/antd.less ./src/theme/antd.css构建产物: antd.css ,在项目head标签中引入,就完成了UI库的主题适配。

  

自定义样式主题适配实现因为「UI库主题适配实现」中,variable.css设置了CSS变量,所以自定义样式的节点上直接使用var(CSS变量)即可。

  

<div style="color: var(--text-color)"></div>总结本篇文章重点讲「不支多主题的UI库」适配,相信未来所有的UI库都会支持CSS变量实现多主题切换,目前antd正在做这件事,等完全支持后,多主题适配需要关心的是自定义UI库样式和自定义样式主题适配。

  

如果你有更好的主题适配方案,欢迎一起讨论。

相关文章