首页/文章/前端

实现主题换肤( CSS 变量 + 类名切换)

2024-04-25
6283 分钟
...

实战引入:CSS变量 + 类名切换

通过arco-design组件库的使用来了解如何切换主题

主要思路:CSS变量 + 类名切换(组件库提供/自己定义) + 将当前主题模式设置到localStorage + vuex状态管理theme

  1. 定义CSS变量:因为CSS变量组件库已经配好一套黑白变量了,直接拿来用arco.design/vue/docs/to…

  2. 为body标签添加相关的属性,参考arcodesign官网:

设置到localStorage防止刷新之后主题恢复成默认的配置

const isLight = ref();
const theme = ref();
const toggleLight = () => {
  isLight.value = true;
  
  document.body.removeAttribute("arco-theme");
  localStorage.setItem("theme", "light");
};
const toggleDark = () => {
  isLight.value = false;
  
  document.body.setAttribute("arco-theme", "dark");
  localStorage.setItem("theme", "dark");
};
onMounted(() => {
  theme.value = localStorage.getItem("theme");
  if (theme.value === "light") {
    toggleLight();
  } else {
    toggleDark();
  }
});
  1. 将一些写死的样式改为变量:

如果觉得官网设计的变量不够,想自己加,可以参考: arco.design/vue/docs/th…
利用组件库平台提供去配置主题: arco.design/docs/design…

Tailwind颜色主题切换

html 代码

<div class="relative flex flex-col justify-center overflow-hidden bg-gray-50 py-6 sm:py-12">
  <div class="relative px-6 pt-10 pb-8 shadow-xl ring-1 ring-gray-900/5 sm:mx-auto sm:max-w-lg sm:rounded-lg sm:px-10">
    <div class="mx-auto max-w-md">
      <div class="divide-y divide-gray-300/50">
        <div class="space-y-6 py-8 text-base leading-7 text-gray-600">
          <div class="font-medium text-xl"></div>
          <p class="text-xl font-bold text-gray-90 text-center">Thank you 🙏</p>
          <div class="text-sm text-gray-500">We appreciate your support.</div>
        </div>
      </div>
    </div>
  </div>
</div>
</div>

更多颜色: https://tailwindcss.com/docs/customizing-colors 配置文件中进行配置:style.css,将一些基础样式添加到 Tailwind 的基础层,定义颜色变量

@tailwind base;
@tailwind components;
@tailwind utilities;


使用@layer 指令将这些样式添加到 Tailwind 的基础层*/
@layer base {
  .theme-light {
    --color-base: theme('colors.white'); 
    --color-text-base: theme('colors.black'); 
    --color-off-base: theme('colors.gray.50');
    --color-text-muted: theme('colors.gray.600');
    --color-text-muted-hover: theme('colors.gray.500'); 
    --color-primary: theme('colors.blue.600'); 
    --color-secondary:theme('colors.blue.300'); 
  }

  .theme-dark {
    --color-base: theme('colors.gray.900');
    --color-text-base: theme('colors.gray.100'); 
    --color-off-base: theme('colors.gray.800'); 
    --color-text-muted:theme('colors.gray.300'); 
    --color-text-muted-hover: theme('colors.gray.200');
    --color-primary: theme('colors.blue.500'); 
    --color-secondary: theme('colors.blue.200'); 
  }
}

配置文件中进行配置:tailwind.config.js,定义了一些背景色和文本颜色的 utility classes

module.exports = {
  mode: 'jit',
  theme: {
    extend: {},
    backgroundColor: {
      
      base: 'var(--color-base)',
      'off-base': 'var(--color-off-base)',
      primary: 'var(--color-primary)',
      secondary: 'var(--color-secondary)',
      muted: 'var(--color-text-muted)',
    },
    textColor: {
      
      base: 'var(--color-text-base)',
      muted: 'var(--color-text-muted)',
      'muted-hover': 'var(--color-text-muted-hover)',
      primary: 'var(--color-primary)',
      secondary: 'var(--color-secondary)',
    },
  },
  variants: {},
  plugins: [],
}

在html相关的地方添加上相关的class就行了:
例如,
在需要应用相应主题样式的地方的父元素或自身元素上添加主题的标签: theme-light
在需要改变背景的地方添加上:bg-base

代码:Tailwind Play

unocss颜色主题切换

html代码

<div class="relative flex flex-col justify-center overflow-hidden bg-gray-50 py-6 sm:py-12">
  <div class="relative px-6 pt-10 pb-8 shadow-xl ring-1 ring-gray-900/5 sm:mx-auto sm:max-w-lg sm:rounded-lg sm:px-10">
    <div class="mx-auto max-w-md">
      <div class="divide-y divide-gray-300/50">
        <div class="space-y-6 py-8 text-base leading-7 text-gray-600">
          <div class="font-medium text-xl"></div>
          <p class="text-xl font-bold text-gray-90 text-center">Thank you 🙏</p>
          <div class="text-sm text-base">We appreciate your support.</div>
        </div>
      </div>
    </div>
  </div>
</div>
</div>

配置文件中unocss.config.ts进行配置shortcut

export default defineConfig({
    ... ...
    shortcuts:{
        'bg-base': 'bg-[#ffffff] dark:bg-[#20202a]',
        'card-base': 'bg-[#ffffff] dark:bg-[#10101a]',
        'text-base': 'text-[#20202a] dark:text-[#f0f0f0]',
    },
    ... ...
})

在html添加相关标签就行 代码:UnoCSS Playground

总结

上面的三个切换主题都是是基于CSS变量 + 类名切换

拓展

推荐文章:前端主题切换方案 - 掘金
6种方案:

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
前端2026-07-17
HTML Form 可以把 POST 响应加载进 iframe
在接入支付验证、身份认证或第三方授权页面时,我们经常会遇到这样的流程: 1. 后端返回一个第三方接口地址。 2. 这个地址必须通过 请求访问。 3. 接口返回 HTML,或者重定向到真正的验证页面。 4. 验证页面需要嵌入当前网站,而不是打开新标签页。 5. 验证完成后,当前页面继续执行后续业务。 第一次遇到这个需求,很容易想到: 但涉及第三方支付时,这种方式通常会遇到 CORS、Cookie、重定向和跨域页面读取限制。 实际上,HTM...
学习
前端2026-05-29
前端判断一个网页是否允许被 iframe 内嵌
前端 不能 100% 准确提前判断 一个网页是否允许被 iframe 内嵌,因为决定权主要在目标网站返回的 HTTP 响应头 里,而普通前端 JS 通常读不到跨域页面的响应头。 核心判断看这两个东西: 1. 老一点但仍常见。 表示完全不允许被 iframe 嵌入。 表示只允许同源页面 iframe 嵌入。 以前有这个,但现代浏览器支持很差,基本不建议依赖。 2. 现在更推荐看这个。 表示不允许任何页面嵌入。 表示只允许同源嵌入。 表示只...
学习
前端2026-03-20
网页唤起 Android App 调试笔记(App Links)
&nbsp; 在最近的项目中,我遇到了 网页访问特定 URL 应该唤起 Android App,但实际只打开网页 的问题。通过调试和排查,整理出以下经验和步骤。 1\. 项目与环境信息(脱敏处理) 网站域名: 唤起页面: Android App 包名: intent filter 配置示例: assetlinks.json 已上线,包含 App 的 SHA256 签名指纹 2\. 问题现象 用户访问 页面时, 网页打开了,但 App 没...
学习
前端2026-03-02
深入理解 Cookie:安全属性、访问边界与渲染场景实践
本文系统梳理 Cookie 核心机制,聚焦 HttpOnly/SameSite 等安全属性 、 访问权限边界 、 CSR/SSR 差异 ,附关键代码示例与安全清单。适合开发查阅与知识沉淀。 一、Cookie 是什么?为什么需要它? HTTP 是无状态协议。Cookie 是服务端通过 响应头下发、浏览器自动存储并在后续 同源请求中携带 的小型文本数据(通常 ≤4KB),用于: 会话维持(Session ID) 用户偏好(语言/主题) 跨请...
学习
前端2026-03-02
退出登录时 Cookie 清除指南
核心结论 :登出 ≠ 单方面操作。HttpOnly 与非 HttpOnly Cookie 需 前后端协同清除 ,缺一不可。残留 Cookie = 安全隐患 + 用户体验漏洞。 🔒 为什么不能“一键清空”? 浏览器出于安全设计: 后端 :只能通过 响应头清除 自己设置过 的 Cookie(需属性完全匹配) 前端 JS :可读写非 HttpOnly Cookie,但 无法触碰 HttpOnly Cookie 无“清除全部”API :任何服...
学习
前端2025-12-15
懒加载图片在同一个 Item 中逐个出现的原因与解决方案
懒加载图片在同一个 Item 中逐个出现的原因与解决方案 适用场景 :使用原生 实现图片懒加载的动态列表,每个列表项(item)包含多张图片。 📌 问题描述 在开发一个动态渲染的列表时,每个 item 中包含三张图片,并使用 HTML 原生的懒加载属性: 观察到的现象: 开启懒加载时 :三张图片 不是同时出现 ,而是 从左到右(或从上到下)依次加载显示 ,有明显的时间差。 关闭懒加载(移除 )后 :三张图片 看起来是一起出现的 ,视觉...
学习

评论

请登录后发表评论

去登录
加载评论中...

目录