前端主题切换的多种方式

动态link标签加载不同主题css

**原理:**提前准备好几套CSS主题样式文件,在点击切换主题时,创建link标签动态加载到head标签中,或者是动态改变link标签的href属性。
缺点:

动态加载样式文件,如果文件过大网络情况不佳的情况下可能会有加载延迟,导致样式切换不流畅

维护不便!

**优点:**实现了按需加载,提高了首屏加载时的性能且兼容性好

  1. 先创建主题css文件dark.csslight.css
  2. html中link引入
html 复制代码
<head>
	<link rel="stylesheet" href="./css/dark.css" >
	<link rel="stylesheet" href="./css/light.css" disable>
</head>
  1. 切换主题
typescript 复制代码
const themesCssSheet = [
	document.querySelector("link[data-theme='light']"),
	document.querySelector("link[data-theme='dark']"),
]
btn.addEventlistner("click",()=>{
	const dataTheme = btn.getAttribute("data-theme")
	themesCssSheet.forEach(theme=>{
		t.disable = theme.dataset.theme === dataTheme 
	})
})

提前引入不同主题的css样式,通过切换类名切换主题

  1. 定义好css样式
css 复制代码
/* light样式主题 */
body{
  color: #f90;
  background: #fff;
  --text-color:black
  --header-bg:orange
}
/* dark样式主题 */
.dark {
  color: #eee;
  background: #333;
  --text-color:#fff
  --header-bg:blue
}
  1. 点击切换主题时 js切换
typescript 复制代码
document.body.classList.toggle("dark")

css预编译器

scss 复制代码
$themes:(
	light:(
		textColor:black
		headerBg:orange
	),
	dark:(
		textColor:#fff
		headerBg:blue
	)
)
$currentTheme:light;
@mixin changeTheme(){
	@each $key,$value in $themes{
		$currentTheme:$key !global;
		html[data-theme='#{$key}'] & {
			@content;
		}
	}
}

@function getTextColor(){
	$currentThemeObj: map-get($themes,$curTheme);
	@return map-get($currentThemeObj,"textColor");
}
@function getHeaderBg(){
	$currentThemeObj: map-get($themes,$curTheme);
	@return map-get($currentThemeObj,"headerBg");
}

@function getThemeValue($key){
	$currentThemeObj: map-get($themes,$curTheme);
	@return map-get($currentThemeObj,$key);
}
.content{
	width:100%;
	height:100%;
	@changeTheme{
		textColor:getTextColor();
		headerBg:getHeaderBg();
	}
}

基于CSS变量(最优方式)

原理 :根据html元素标签的属性切换所使用的主题变量。
缺点 :IE兼容性不行(基本可以忽略)。
优点:便于维护,基本无需css参与

  1. 定义两套(多主体多套)变量
css 复制代码
:root{
	--text-color:black
	--header-bg:orange
	...
}
// 暗色主题
html[data-theme='dark']{
	--text-color:#fff
	--header-bg:blue
	...
}
  1. 在main.js项目入口文件导入该变量,便于组件使用
  2. 组件中主题相关的直接使用变量
  3. 主题切换时
typescript 复制代码
type Theme = "dark" | "light"
export const changeTheme = (theme:Theme )=>{
	document.documentElement.dataset.theme = theme
}

CSS变量+动态setProperty

  1. 定义变量
css 复制代码
:root{
	--text-color:black
	--header-bg:orange
	...
}
  1. 定义js更改属性值方法
typescript 复制代码
export const setCssVar = (prop: string, val: any, dom = document.documentElement) => {
  dom.style.setProperty(prop, val)
}
// 当样式改变
setCssVar('--text-color', color)

总结

还有其他方式(例如vue3 v-bind css,变量和类名结合),但是总体都大同小异。

相关推荐
华玥作者19 小时前
[特殊字符] VitePress 对接 Algolia AI 问答(DocSearch + AI Search)完整实战(下)
前端·人工智能·ai
AAD5558889919 小时前
YOLO11-EfficientRepBiPAN载重汽车轮胎热成像检测与分类_3
人工智能·分类·数据挖掘
王建文go19 小时前
RAG(宠物健康AI)
人工智能·宠物·rag
ALINX技术博客20 小时前
【202601芯动态】全球 FPGA 异构热潮,ALINX 高性能异构新品预告
人工智能·fpga开发·gpu算力·fpga
易营宝20 小时前
多语言网站建设避坑指南:既要“数据同步”,又能“按市场个性化”,别踩这 5 个坑
大数据·人工智能
春日见20 小时前
vscode代码无法跳转
大数据·人工智能·深度学习·elasticsearch·搜索引擎
darkb1rd20 小时前
四、PHP文件包含漏洞深度解析
网络·安全·php
Drgfd21 小时前
真智能 vs 伪智能:天选 WE H7 Lite 用 AI 人脸识别 + 呼吸灯带,重新定义智能化充电桩
人工智能·智能充电桩·家用充电桩·充电桩推荐
萤丰信息21 小时前
AI 筑基・生态共荣:智慧园区的价值重构与未来新途
大数据·运维·人工智能·科技·智慧城市·智慧园区
盖雅工场21 小时前
排班+成本双管控,餐饮零售精细化运营破局
人工智能·零售餐饮·ai智能排班