网页主题自动适配:网页跟随系统自动切换主题

主题切换是网站设计中一个非常有趣的功能,它允许用户在多种预先设计的样式之间轻松切换,以改变网站的视觉表现。最常见的就是白天和黑夜主题的切换,用户可以根据自己的喜好进行设置。
除了让用户手动去切换主题外,如果能够让用户第一次访问时,网站就设置为用户系统的主题样式,这无疑是一种更好的体验。

主题切换

CSS主题切换有多种方式实现,这里就简单描述下,不是本文重点

方式1:通过自定义标签属性来实现主题切换

/* 默认主题样式 */
body {background-color: white;color: black;
}/* 深色主题样式 */
body[data-theme="dark"] {background-color: black;color: white;
}
:root {--body-background: rgb(248, 244, 212);--text-color: #000;
}
html[data-theme="dark"] {--body-background: rgb(58, 70, 90);--text-color: #eee;
}

方式2:运行时动态地修改CSS变量的值,从而实现主题切换的效果

:root {--primary-color: #007bff;--secondary-color: #6c757d;--background-color: white;--text-color: black;
}
​
body {background-color: var(--background-color);color: var(--text-color);
}
document.documentElement.style.setProperty('--background-color', 'black');
document.documentElement.style.setProperty('--text-color', 'white');

方式3:使用类名切换,通过对顶层节点设置不同的类名,然后定义不同类名的CSS样式,切换主题时修改类名即可

.theme-light {background-color: white;color: black;
}
​
.theme-dark {background-color: black;color: white;
}
function switchTheme() {const bodyElement = document.body;if (bodyElement.classList.contains('theme-light')) {bodyElement.classList.remove('theme-light');bodyElement.classList.add('theme-dark');} else {bodyElement.classList.remove('theme-dark');bodyElement.classList.add('theme-light');}
}


方式4:link标签动态引入

function switchTheme(theme) {const linkElement = document.createElement('link');linkElement.rel = 'stylesheet';if (theme === 'light') {linkElement.href = 'theme-light.css'; // 切换为浅色主题} else {linkElement.href = 'theme-dark.css'; // 切换为深色主题}
​document.head.appendChild(linkElement);
}

扫码加入前端交流群,期待你的加入!
描述文字

CSS媒体查询

CSS媒体查询是实现响应式网页设计的重要工具,它允许根据设备的特定特性来应用不同的样式规则。

使用 @media 规则可以实现这一功能,通过这个规则可以定义一个或多个条件,当这些条件满足时,相应的样式代码块将会被应用到文档上。例如,在屏幕宽度小于或等于768像素时,背景颜色可以设置为浅蓝色

/* 基础样式 */
body {background-color: lightblue;color: white;font-size: 16px;padding: 20px;
}/* 当屏幕宽度小于或等于768像素时,应用以下样式 */
@media (max-width: 768px) {body {background-color: red;color: black;font-size: 14px;padding: 10px;}
}

CSS媒体查询还可以检测用户是否有将系统的主题色设置为两色或者暗色

  • light:表示用户已告知系统选择使用浅色主题界面
  • dark:表示用户已告知系统选择使用暗色主题界面
.day {background: #eee;color: black;
}
.night {background: #333;color: white;
}@media (prefers-color-scheme: dark) {.day.dark-scheme {background: #333;color: white;}.night.dark-scheme {background: black;color: #ddd;}
}@media (prefers-color-scheme: light) {.day.light-scheme {background: white;color: #555;}.night.light-scheme {background: #eee;color: black;}
}

这种方式的确可以实现主题跟随系统的变换而变换,但是存在以下缺点:

  • 增加工作量:开发者需要编写更多的CSS代码,这可能会导致工作效率降低

  • 加载时间延长:随着CSS代码量的增加,页面的加载时间可能会变长,尤其是对于那些包含大量媒体查询的复杂样式表

  • 用户无法自定义:样式固定,用户无法自定义设置主题样式

JS媒体查询

JS同样拥有媒体查询的方法 matchMedia()。传入一个被用于媒体查询解析的字符串,返回一个用来媒体查询新的 MediaQueryList 对象,其中的 matchs 属性值就是匹配结果。

// 如果视口的宽度小于或等于600像素,则输出为true
const mql = window.matchMedia('(max-width: 600px)');
console.log(mql.matchs)

同样的也可以用来查询系统是否使用了暗色主题

const osThemeIsDark = matchMedia("(prefers-color-scheme: dark)").matches;

接下来就采用上面方式1的主题切换方案,结合JS媒体查询来实现跟随系统主题切换的功能。

:root {--body-background: rgb(248, 244, 212);--text-color: #000;
}
html[data-theme="dark"] {--body-background: rgb(58, 70, 90);--text-color: #eee;
}
body {padding-top: 200px;height: 100vh;width: 100vw;margin: 0;background: var(--body-background);text-align: center;color: var(--text-color);
}
<body><div><select><option value="light">白天模式</option><option value="dark">黑夜模式</option><option value="os">跟随系统</option></select></div><h1>公众号:前端筱园</h1><p>www.dengzhanyong.com</p>
</body>
const select = document.querySelector('select');
const html = document.querySelector("html");
// 获取用户设置的主题,默认是跟随系统
const localTheme = localStorage.getItem('theme') || 'os';
settingTheme(localTheme);
// 设置select选中的值
select.value = localTheme;
​
select.onchange = (e) => {
const theme = e.target.value;settingTheme(theme);localStorage.setItem('theme', theme)
}function settingTheme(theme) {// 如果是跟随系统,就获取系统的主题
if (theme === 'os') {
const osThemeIsDark = matchMedia("(prefers-color-scheme: dark)").matches;html.dataset.theme = osThemeIsDark ? 'dark' : 'light';} else {html.dataset.theme = theme;}
}

监听媒体变化

现在还有一个问题,如果页面已经打开的情况下,再去修改系统主题,是否能检测到系统主题的变化,使得网页在不刷新的情况下自动切换。

答案是可以的,可以通过监听 MediaQueryListchange 事件,当 matches 的值发生变化时会触发。

matchMedia("(prefers-color-scheme: dark)").addEventListener("change", event => {html.dataset.theme = event.matches ? 'dark' : 'light';
})

利用媒体查询还可以检测很多内容,比如:浏览器可视区域尺寸、设备尺寸、设备目前处于横向还是纵向、检测设备宽高比、设备颜色位数等

写在最后

欢迎访问我的个人网站:www.dengzhanyong.com

前端筱园交流群】已经正式开通啦!在这里,你可以与一群志同道合的小伙伴们交流、分享、学习、共同成长,扫码加入,期待你的加入!
描述文字
关注我的公众号【前端筱园】,不错过每一篇推送

描述文字

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

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

相关文章

ChatGLM3大模型本地化部署、应用开发与微调

文章目录 写在前面ChatGLM3推荐图书作者简介推荐理由粉丝福利写在后面 写在前面 本期博主给大家推荐一本初学者学习并部署大模型的入门书籍&#xff0c;一起来看看吧&#xff01; ChatGLM3 ChatGLM3是继一系列先进语言模型之后的又一力作&#xff0c;专为追求高精度和广泛适…

计算机发展史故事【6】

电脑群英谱 本世纪三、四十年代&#xff0c;是计算机发展史里最重大的收获季节。群英荟萃&#xff0c;逐鹿中原&#xff0c;鹿究竟死于谁手&#xff0c;并不是没有争议的。除了马克1 号与埃历阿克&#xff0c;还有一大批科学家为计算机的诞生作出过巨大的贡献&#xff0c;他们…

智慧变电站守护者:TSINGSEE青犀AI视频智能管理系统引领行业革新

一、方案概述 随着科技的不断进步&#xff0c;人工智能&#xff08;AI&#xff09;技术已经深入到各个领域。在变电站安全监控领域&#xff0c;引入AI视频监控智能分析系统&#xff0c;可以实现对站内环境、设备状态的实时监控与智能分析&#xff0c;从而提高变电站的安全运行…

docker-compose集成elk(基于logstash+filebeat)采集java和nginx日志

1.准备compose.yml编排式文件 services: #日志信息同步logstash:container_name: logstashimage: docker.elastic.co/logstash/logstash:7.17.14 #logstash:command: logstash -f /usr/share/logstash/pipeline/logstash.confdepends_on:- elasticsearchrestart: on-failurepo…

解决$‘\r‘: command not found 或syntax error near unexpected token `$‘\r‘的四个方法

问题原因&#xff1a; 两个报错原因都是Linux和windows下的回车换行符不兼容 解决方法&#xff1a; 方法一&#xff1a;在windows系统可以用文本编辑器查看所有字符&#xff0c;例如notepad&#xff0c;编辑->档案格式转换->转换为UNIX格式 方法二&#xff1a;在Linux系…

Vue的省份联动

Vue的省份联动 一、安装依赖库 npm install element-china-area-data -Snpm install element-ui --save全局使用elemntui组件库 import ElementUI from element-ui; import element-ui/lib/theme-chalk/index.css;Vue.use(ElementUI);二 、代码如下 <template><div…

一、手写一个uart协议——rs232

先了解一下关于uart和rs232的基础知识 文章目录 一、RS232的回环测试1.1模块整体架构1.2 rx模块设计1.2.1 波形设计1.2.2代码实现与tb1.2.4 仿真 1.3 tx模块设计1.3.1 波形设计1.3.2 代码实现与tb1.3.4 顶层设计1.3.3 仿真 本篇内容&#xff1a; 一、RS232的回环测试 上位机…

制造业的智慧进化:机器学习与人工智能的全方位渗透

&#x1f9d1; 作者简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

地图位置的二维码怎么做?在线制作地图二维码的方法

怎么定位一个位置做成二维码呢&#xff1f;随着互联网的不断发展&#xff0c;现在通过扫描二维码来获取导航位置的方式有很多的场景都在应用。这种方式的好处在于其他人都可以通过这个二维码来获取位置&#xff0c;有利于分享。 导航地图二维码可以在电脑的二维码生成器上快速…

爬虫爬取必应和百度搜索界面的图片

爬虫爬取必应和百度搜索界面的图片 爬取bing搜索图片界面爬取百度搜索界面图片结果如下 爬取bing搜索图片界面 浏览器驱动下载地址 对应版本即可 浏览器驱动 mad直接用 import os import re from selenium import webdriver from selenium.webdriver import Keys from sel…

【ACM出版】第四届控制与智能机器人国际学术会议(ICCIR 2024)

第四届控制与智能机器人国际学术会议&#xff08;ICCIR 2024&#xff09; 2024 4th International Conference on Control and Intelligent Robotics 2024年6月21日-23日 | 中国-广州 官网&#xff1a;www.ic-cir.org EI、Scopus双检索 投稿免费参会、口头汇报及海报展示 四…

leetcode63.跳跃游戏2(动态规划)

问题描述&#xff1a; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物…

vue3+vite+axios+ElementPlus+ElLoading简易封装

1.安装按需加载element-plus需要的依赖包 pnpm install element-pluspnpm install axios# 按需自动导入 pnpm install -D unplugin-vue-components unplugin-auto-import# 自动导入element-plus样式 pnpm install -D vite-plugin-style-import2.修改jsconfig.json {"com…

基于scarpy框架的肯德基中国门店信息获取

基于scarpy框架的肯德基中国门店信息获取 一.项目流程二.对爬虫文件进行编写三.对管道进行编写 一.项目流程 scrapy基础知识: https://blog.csdn.net/qq_44907926/article/details/119531324 1.创建scrapy项目:scrapy startproject <项目名> 2.在项目中生成一个爬虫: sc…

某票星球网图标点选验证码YOLOV8识别案例

注意,本文只提供学习的思路,严禁违反法律以及破坏信息系统等行为,本文只提供思路 如有侵犯,请联系作者下架 图标点选验证码大家都不陌生了,我们来看下数据集 引言与个人想法 先说结论,本文采用的方法能够达到99的准确率,效果图如下 做图标点选其实方法有很多,有的…

使用网络工具监控网络性能

网络工具和实用程序有助于有效地检测网络问题&#xff0c;诊断其原因和位置&#xff0c;以及缓解和解决问题&#xff0c;这有助于确保网络环境的稳定性&#xff0c;使用户免受设备连接问题带来的麻烦。 网络工具已经成为每个网络管理员用于有效诊断和处理网络问题的解决方案中…

暴露自己IP地址有什么危险

暴露自己的IP地址确实存在一定的危险性&#xff0c;以下是关于这一问题的详细探讨&#xff1a; 一、IP地址的重要性 IP地址是互联网通信中的关键标识&#xff0c;它使得网络中的设备能够相互识别并进行数据传输。在网络世界中&#xff0c;每台设备都需要一个独特的IP地址来确…

斯坦福大学的在线密码学课程

密码学是保护计算机系统信息不可或缺的工具。在本课程中&#xff0c;您将了解密码系统的内部工作原理&#xff0c;以及如何在实际应用中正确使用它们。课程首先将详细讨论当强大的对手窃听和篡改流量时&#xff0c;拥有共享密钥的双方如何进行安全通信。我们将研究许多已部署的…

SAP sq01,sq02,sq03创建query报表

步骤&#xff1a;1&#xff0c;SQ03创建用户组&#xff08;User Group&#xff09; 2&#xff0c;SQ02创建信息集&#xff08;InfoSet&#xff09; 3&#xff0c;SQ03分配用户和InfoSet 4&#xff0c;SQ01创建查询 5&#xff0c;SE93给Query分配Tcode 1&#xff0c;SQ03创建用…

ifconfig命令找不到 command not found

问题 今天解决虚拟机的网络问题后&#xff0c;使用ifconfig发现报错命令未找到 解决方案 输入yum install ifconfi的程序安装包 yum install ifconfig 如果显示没有可用软件包 ifconfig&#xff0c;错误&#xff1a;。 就输入yum search ifconfig匹配安装包程序 yum searc…