如何为已制作的明暗主题切换按钮添加对应主题切换功能
明暗模式切换功能实现
你已完成的开关样式已经可以正常反馈状态,只需要补充全局主题变量定义和交互逻辑即可实现完整的明暗模式切换功能,具体实现方案如下:
- 在
:root伪类中定义亮色主题的全局CSS变量,新增.dark类对应暗色主题的变量,所有页面元素的颜色、背景样式都引用这些变量,切换时仅需修改根元素的类即可全局生效 - 给开关的复选框绑定
change事件,根据选中状态切换根元素的主题类,同时将当前主题状态存入localStorage实现持久化,用户下次打开页面自动沿用上次的选择 - 页面初始化时读取
localStorage存储的主题状态,自动设置对应开关状态和页面主题
完整可运行代码
<body> <div class="theme-toggle" style="cursor: pointer;"> <input type="checkbox" checked style="cursor: pointer;" id="themeToggle"> <div class="toggle-body" style="cursor: pointer;"></div> <div class="celestial-body" style="cursor: pointer;"></div> </div> <style> :root { --width: 60px; --height: 30px; /* 亮色主题全局变量 */ --page-bg: #ffffff; --text-color: #1a1a1a; } /* 暗色主题全局变量 */ :root.dark { --page-bg: #1a1a1a; --text-color: #f0f0f0; } body { font-family: monaco, sans-serif; box-sizing: border-box; margin: 0; padding: 0; margin: 2em; /* 引用主题变量 */ background: var(--page-bg); color: var(--text-color); transition: background 0.2s ease, color 0.2s ease; } .theme-toggle { position: relative; width: var(--width); height: var(--height); } .theme-toggle input[type="checkbox"] { position: absolute; top: 0; left: 0; opacity: 0; z-index: 1; width: var(--width); height: var(--height); } .theme-toggle .toggle-body { position: absolute; top: 0; left: 0; width: var(--width); height: var(--height); border: 2px solid #080808; border-radius: var(--height); transition: all 80ms ease-in-out; } .theme-toggle input[type="checkbox"]~.toggle-body { background: #1d1d1d; background-image: url("https://cdn.glitch.com/9be3ef5e-cf68-4fac-9bd5-82714468aed6%2F1e7b6b11b5b398711c60f2b71cdf9b03.gif?v=1599237363310"); background-size: cover; } .theme-toggle input[type="checkbox"]:checked~.toggle-body { background: #82dfff; background-image: url(""); background-size: cover; border-color: #89cbf9; } .theme-toggle input[type="checkbox"]~.celestial-body { position: absolute; width: 24px; height: 24px; border: 2px solid #fff08e; border-radius: 100%; background: #fff5c4; transition: all 80ms ease-in-out; } .theme-toggle input[type="checkbox"]:not(:checked)~.celestial-body { top: 3px; left: 3px; } .theme-toggle input[type="checkbox"]:checked~.celestial-body { top: 3px; left: calc(100% - 27px); background: #ff9900; border-color: #ddceb1; } .theme-toggle input[type="checkbox"]~.celestial-body::after { content: " "; opacity: 0; position: absolute; left: -20px; transition: left 0.13s ease-in, opacity 0.15s ease-out; } .theme-toggle input[type="checkbox"]:checked~.celestial-body::after { content: ""; position: absolute; bottom: -2px; left: -10px; display: block; opacity: 1; width: 20px; height: 20px; background: url("https://cdn.glitch.com/9be3ef5e-cf68-4fac-9bd5-82714468aed6%2FVector%201%20(1).svg?v=1599249814204"); background-size: contain; background-position: left; background-repeat: no-repeat; } </style> <script> const themeToggle = document.getElementById('themeToggle'); const rootEl = document.documentElement; // 页面加载时初始化主题 const savedTheme = localStorage.getItem('site-theme'); if (savedTheme === 'dark') { rootEl.classList.add('dark'); themeToggle.checked = false; } // 绑定切换事件 themeToggle.addEventListener('change', () => { if (themeToggle.checked) { rootEl.classList.remove('dark'); localStorage.setItem('site-theme', 'light'); } else { rootEl.classList.add('dark'); localStorage.setItem('site-theme', 'dark'); } }); </script> </body>
后续开发页面其他元素时,颜色相关样式直接引用已定义的全局变量即可,无需单独编写两套样式,切换主题时会自动适配。
内容的提问来源于stack exchange,提问作者Harsh Sharma
相关产品推荐
相关产品推荐

