前端主题切换的几种实现
几种方案实现主题切换,适用于预设主题和自定义主题,可以根据实际需要和实现复杂度灵活选择。
滤镜
使用css filter
,直接进行页面整体颜色转换,进行主题切换
1 | const switchTheme = theme => { |
直接整体使用的话,不仅会将元素进行过滤,同时对图片、视频也会生效,需要特殊处理,让图片、视频保持正常显示。
1 | img:not([src*='.svg']), video { |
一些特殊节日需要使网站整体变灰
1 | :root { |
link标签动态引入(主题变量)
提前定义几套CSS主题样式文件,切换主题时,创建link
标签动态插入到head
标签中,或者动态修改link
标签的href
属性
1 | export function preLoadStyles(styles: Array<string>, callback?: () => void) { |
优点:
- 实现按需加载,提升首屏加载性能
- 修改CSS变量即可修改主题,新增/修改方便
缺点
- 动态加载样式文件,如果文件过大可能有加载延迟,切换不流畅
加载全部主题文件(主题变量),用类名进行切换
将所有主题文件引入,切换整体的类名,使不同主题生效
1 | function change(theme) { |
优点:
- 切换样式不会卡顿
缺点
- 首屏加载时间增加
CSS变量+动态setProperty
前面方法主要适用于预设好的几种主题,此方案适用于用于根据颜色面板自定义主体色
定义一个工具类方法,用于修改指定的CSS变量值,调用的是CSSStyleDeclaration.setProperty
1 | // 预设主体色 |
1 | export const setCssVar = (prop: string, val: any, dom = document.documentElement) => { |
1 | setCssVar('--theme-color', color) |
优点:
- 不用重新加载样式文件,切换流畅
- 可以实时自定义主体色
缺点
- 暂无
总结
固定预设主题样式:适合link标签动态引入(主题变量)
主题样式不固定:适合CSS变量+动态setProperty