Tailwind CSS 实战,基于 Kooboo 构建 AI 对话框页面(三):实现暗黑模式主题切换

基于前两篇的内容,为页面添加主题切换功能,实现网站页面的暗黑模式: 

Tailwind css实战,基于Kooboo构建AI对话框页面(一)-CSDN博客

Tailwind css实战,基于Kooboo构建AI对话框页面(二)-CSDN博客


在前两篇内容的基础上,为页面新增暗黑 / 亮色双主题切换功能,完善用户体验。最终效果如下:


一、暗黑模式的需求与价值

  1. 用户体验升级:提供亮色 / 暗黑主题切换,适配不同使用场景(如夜间阅读、视觉偏好),提升产品包容性。
  2. 视觉一致性:通过 CSS 变量统一管理颜色,确保主题切换时界面元素(如聊天气泡、按钮、文本)的样式协调。
  3. 技术挑战:如何实现动态主题切换、持久化存储用户偏好。

二、暗黑模式技术实现(核心代码解析)

1. CSS 变量定义:主题解耦

在 CSS 中,通过:root伪类定义的变量是全局作用域的,它代表了文档的根元素(在 HTML 中就是<html>元素)。这里定义的变量是亮色主题(也就是默认主题)下的颜色值。

<style>/* 亮色主题(默认) */:root {--bg-primary: #ffffff;--bg-secondary: #f8f9fa;--bg-tertiary: #e9ecef;--border-color: #dee2e6;--text-primary: #333333;--text-secondary: #6c757d;--text-tertiary: #e5e7eb;--chat-bubble: #ffffff;--chat-bubble-ai: #f8f9fa;}/* 暗黑主题 */.dark {--bg-primary: #1e293b;--bg-secondary: #0f172a;--bg-tertiary: #334155;--border-color: #4b5563;--text-primary: #f3f4f6;--text-secondary: #9ca3af;--text-tertiary: #1f2937;--chat-bubble: #334155;--chat-bubble-ai: #1e293b;}</style>

作用:通过 :root 和 .dark 类定义全局颜色变量,后续样式直接引用变量(如 bg-[var(--bg-primary)]),实现主题 “一键切换”。

  • Tailwind 整合:利用 var() 函数与 Tailwind 的自定义值([] 语法)结合,如background-color: var(--bg-primary);无需重复编写暗黑模式专属类。
2. 切换按钮 UI(HTML + Tailwind)

从 HTML 结构来看,这是一个用于切换暗黑模式的按钮。id="darkModeToggle"为按钮赋予了唯一标识,方便在 JavaScript 中获取和操作

<!-- 暗黑模式切换按钮 --><button id="darkModeToggle" class="fixed top-4 right-4 z-10 bg-[var(--bg-primary)] text-[var(--text-primary)] p-2 rounded-full shadow-lg hover:bg-[var(--bg-tertiary)] transition-colors"><i class="fa fa-moon-o dark:hidden"></i><i class="fa fa-sun-o hidden dark:inline"></i></button>
  • 交互设计
    • 固定定位(fixed)确保按钮始终可见;
    • dark:hidden 和 dark:inline 实现图标随主题切换(Tailwind 暗黑模式前缀 dark: 自动匹配 .dark 类);
    • hover 效果(hover:bg-[var(--bg-tertiary)])增强交互反馈。
3. 主题切换逻辑(JavaScript)
<script>// 暗黑模式切换逻辑document.addEventListener('DOMContentLoaded', function() {const toggle = document.getElementById('darkModeToggle');const html = document.documentElement;// 检查本地存储中的偏好设置if (localStorage.getItem('darkMode') === 'true' || (localStorage.getItem('darkMode') === null && window.matchMedia('(prefers-color-scheme: dark)').matches)) {html.classList.add('dark');}// 切换事件:更新类名 + 本地存储toggle.addEventListener('click', function() {html.classList.toggle('dark');localStorage.setItem('darkMode', html.classList.contains('dark'));});});</script>

这段 JavaScript 代码的作用是实现暗黑模式的切换逻辑和用户偏好的管理:

  • document.addEventListener('DOMContentLoaded', () => {... }):这是一个事件监听器,当页面的 DOM(文档对象模型)加载完成后,才会执行里面的代码。确保在页面元素都加载好之后再进行操作,避免获取不到元素的情况。
  • const toggle = document.getElementById('darkModeToggle');:通过id获取到页面上的暗黑模式切换按钮元素

核心逻辑

  • 持久化存储:通过 localStorage 记录用户选择,刷新页面后保持主题;
  • 系统主题适配:首次访问时,若用户系统偏好暗黑模式(prefers-color-scheme: dark),自动启用暗黑主题;
  • 性能优化:直接操作 document.documentElement(HTML 根元素)的 classList,确保样式切换无延迟。

三、与前两章内容的整合

  1. 容器样式与 CSS 变量深度绑定
    在 HTML 中通过 bg-[var(--bg-primary)] border-[var(--border-color)] 等写法,将容器的背景色、边框色直接关联到 CSS 变量。。例如:

    <!-- 窗口容器 -->
    <div class="max-w-3xl w-full bg-[var(--bg-primary)]      <!-- 主背景色,亮色/暗黑模式自动切换 -->border border-[var(--border-color)]  <!-- 边框色 -->rounded-lg shadow-xl overflow-hidden"><!-- 消息容器 -->
    <div id="messageContainer" class="h-[60vh] overflow-y-auto p-4 space-y-4 bg-[var(--bg-secondary)]"><!-- 输入区域 -->
    <div class="bg-[var(--bg-primary)] p-4 border-t border-[var(--border-color)]">
    优势:所有容器样式通过变量动态控制,一行 CSS 变量修改即可全局响应主题切换,无需逐个组件调整样式,极大提高了开发效率。
  2. 测试场景

    • 手动切换主题,检查所有 UI 元素(背景、文本、边框、图标)是否正确响应;
    • 刷新页面,查看是否会清除本地存储,验证系统主题适配逻辑;
    • 检查移动端(如小屏幕下按钮定位、交互是否正常)。

四、总结

本章通过 CSS 变量 + 本地存储 + 系统主题适配,实现了 AI 对话框的暗黑模式切换,完成了从 静态页面(一)→ 交互逻辑(二)→ 视觉主题优化(三) 的完整实战链路。代码中:

  • Tailwind 与自定义变量的深度整合,简化了主题样式管理;
  • JavaScript 逻辑 确保用户偏好持久化和系统兼容性;
  • UI 细节(如图标切换) 提升了交互体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/web/81656.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

主题阅读输出-关于成年/成熟的认识-01-学习

快速回顾 学习的最终目的&#xff0c;成年人的学习特点&#xff0c;学习对象的选取(学什么)&#xff0c;学习过程的理解&#xff0c;对学习状态的觉察&#xff1b; 参考来源 书籍 《心发怒放的人生》 《我的第一本人生规划手册》 《五维学习力》 《学习的答案》 01-学习是什…

GitLab 18.0 正式发布,15.0 将不再受技术支持,须升级【一】

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 学习极狐GitLab 的相关资料&#xff1a; 极狐GitLab 官网极狐…

Python+Flask+Html做一个简单的测试联调工具

一、场景&#xff1a; 当与外部联调或者内部需要走一些固定流程&#xff0c;且重复的事情&#xff0c;往往需要测试经常性的配合且做重复的工作的联调&#xff0c;这时候需要一些工具作为辅助&#xff0c;或者提供给外部 二、框架&#xff1a; 可以通过PythonFlaskHtml做一个…

Qt5、C++11 获取wifi列表与wifi连接

一、获取wifi列表 .h 文件内容 #include <QWidget> #include <QVBoxLayout> #include <QPushButton> #include <QCheckBox> #include <QListWidget>class Setting : public QWidget {Q_OBJECT public:explicit Setting(QWidget *parent nul…

互联网大厂Java求职面试:AI与大模型应用集成中的架构难题与解决方案-1

互联网大厂Java求职面试&#xff1a;AI与大模型应用集成中的架构难题与解决方案-1 场景描述 郑薪苦&#xff0c;一个看似不靠谱但技术潜力巨大的程序员&#xff0c;在一次针对AI与大模型应用集成的面试中&#xff0c;被一位技术总监级别的人物提问。面试官以严肃专业的态度&a…

SpringMVC实战:动态时钟

引言 在现代 Web 开发中&#xff0c;选择一个合适的框架对于项目的成功至关重要。Spring MVC 作为 Spring 框架的核心模块之一&#xff0c;以其清晰的架构、强大的功能和高度的可配置性&#xff0c;成为了 Java Web 开发领域的主流选择。本文将通过一个“动态时钟”的实战项目…

知行之桥如何将消息推送到钉钉群?

在钉钉平台中&#xff0c;机器人主要分为企业机器人和自定义机器人两类。本文将重点介绍如何通过自定义机器人&#xff0c;实现将知行之桥 EDI 系统的通知消息高效推送至钉钉群&#xff0c;帮助企业第一时间掌握业务动态。 一、在钉钉群中添加自定义机器人 在需要接收知行之桥…

哈工大计算机系统2024大作业——Hello的程序人生

计算机系统 大作业 题 目 程序人生-Hello’s P2P 专 业 人工智能 学   号 2022112040 班 级 2203601 学 生 郄东昕 指 导 教 师 吴锐 计算机科学与技术学院…

联软SDP+安渡:收敛暴露面 从生产网自动取数 安全高效

制造业作为国家经济的基石&#xff0c;其网络安全面临着独特的挑战。出于合规和安全考虑&#xff0c;企业内部往往划分出多个相互隔离的网络区域&#xff0c;如办公网、研发网等&#xff0c;以提升整体安全防护能力。然而&#xff0c;网络隔离在保障安全的同时&#xff0c;也带…

LeetCode 543 二叉树的直径

二叉树的直径&#xff1a;树中任意两个节点间最长路径的长度。这个路径可能经过根节点&#xff0c;也可能不经过。 算法思路 采用深度优先搜索(DFS)的后序遍历方式&#xff0c;计算每个节点的左右子树高度&#xff0c;并在过程中更新最大直径。 代码解析 var diameterOfBin…

构建安全与合规的Jenkins环境:全周期审计方案详解

引言 Jenkins作为最流行的CI/CD工具之一&#xff0c;承载着企业核心的自动化构建与交付流程。然而&#xff0c;随着其复杂性的增加&#xff0c;安全漏洞、权限滥用和合规风险也随之而来。近期频发的供应链攻击&#xff08;如通过恶意插件入侵&#xff09;更是敲响警钟。如何确…

PowerShell Install Sql Server 2025 beta

Sql Server 2025 Download 其它版本和系统自动化脚本下载SQL Server 2025SSMS sql命令行安装ssms 命令行安装网盘分享SQL2025 beta

【K8S】K8S基础概念

一、 K8S组件 1.1 控制平面组件 kube-apiserver&#xff1a;公开 Kubernetes HTTP API 的核心组件服务器。 etcd&#xff1a;具备一致性和高可用性的键值存储&#xff0c;用于所有 API 服务器的数据存储。 kube-scheduler&#xff1a;查找尚未绑定到节点的 Pod&#xff0c;并将…

【C/C++】设计模式之工厂模式:从简单到抽象的演进

文章目录 设计模式之工厂模式&#xff1a;从简单到抽象的演进1 “工厂”模式分类1.1 简单工厂&#xff08;Simple Factory&#xff09;1.2 工厂方法&#xff08;Factory Method&#xff09;1.3 抽象工厂&#xff08;Abstract Factory&#xff09; 2 分析3 总结对比 设计模式之工…

HTTP 与 HTTPS 深度解析:原理、实践与大型项目应用

1. HTTP 与 HTTPS 基础概念 1.1 HTTP&#xff08;超文本传输协议&#xff09; 定义&#xff1a;应用层协议&#xff0c;基于 TCP/IP 通信&#xff0c;默认端口 80 特点&#xff1a; 无状态协议&#xff08;需 Cookie/Session 维护状态&#xff09; 明文传输&#xff08;易被…

【Excel 扩展正则的能力】工作中赋予处理单元格文本的强大正则表达提取能力

文本提取处理领域&#xff0c;正则表达式是最为强大的存在&#xff0c;工作中Excel 是常用的小型数据采集&#xff0c;处理&#xff0c;分析的工具但本身不具备正则的能力&#xff0c;让Excel拥有正则的能力无疑是如虎添翼的能力。 方案 让正则作为函数内容的一部分&#xff0c…

rabbitmq 使用过程中遇到的问题

1. 连接rabbitmq 地址写法&#xff0c;5672 是连接的端口号&#xff0c;15672是页面访问的端口号 2. elasticsearch 的访问端口是9200&#xff0c; 不是9300&#xff0c;9300 是后台通信端口号 &#xff0c;这个页面访问的端口号是一样&#xff0c; 3. rabbitmq 的5种交换接…

HTML实战:响应式个人资料页面

我将创建一个现代化的响应式个人资料页面,展示HTML在实际应用中的强大功能。这个页面将包含多个实战元素:导航栏、个人简介、技能展示、作品集和联系表单。 设计思路 使用Flexbox和Grid布局实现响应式设计 添加CSS过渡效果增强交互体验 实现深色/浅色模式切换功能 创建悬停动…

工业自动化实战:基于 VisionPro 与 C# 的机器视觉 PLC 集成方案

一、背景介绍 在智能制造领域&#xff0c;机器视觉检测与 PLC 控制的无缝集成是实现自动化生产线闭环控制的关键。本文将详细介绍如何使用 C# 开发上位机系统&#xff0c;实现 Cognex VisionPro 视觉系统与西门子 S7 PLC 的数据交互&#xff0c;打造高效、稳定的工业检测方案。…

如何处理 Python 入门难以进步的现象

Python 初学者难以进步的根本原因在于&#xff1a;缺乏项目实践、学习路径不清晰、没有掌握编程思维、忽略调试与源码阅读、缺乏系统性目标驱动。其中&#xff0c;“没有项目驱动导致学习孤岛效应”最为常见且致命。许多初学者只停留在语法知识、刷题阶段&#xff0c;无法构建可…