利用css变量实现切换主题的几种方式

利用css变量实现切换主题的几种方式

这么久就写了一篇文章,今天休假,趁着两个儿子睡着啦来讲讲怎样利用css实现主题的切换。 css变量语法如下,更多css用法参考mdn的 Using_CSS_custom_properties:

/* 定义方式1 */
:root{
  --bodyrgba(0,0,0,0.88);
}

/* 定义方式2 */
[data-theme="light"]{
  --bodyrgba(0,0,0,0.88);
}

实现方式1

一种就是不考虑提供自定义主题,我们设置固定的几套由UI精心设计的主题,相对的css代码会多一些,用户不需要考虑那么多,直接简单切换喜欢的主题。

下面是代码示例:

<!DOCTYPE html>
<!-- 默认主题是在这里设置data-theme属性 -->
<html lang="zh" data-theme="dark">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>样式设置</title>
    <style>

        /* 定义深色主题 */
        [data-theme="dark"] {
            --bodyrgba(0000.88);
            --colorrgba(2552552550.88);
        }

        /* 定义亮色主题 */
        [data-theme="light"] {
            --bodyrgba(2552552550.88);
            --colorrgba(0000.88);
        }  

        body {
            /* 用变量设置界面背景颜色 */
            background-colorvar(--body);
            /* 用变量设置文字颜色 */
            colorvar(--color);
            margin0;
            height100vh;
            display: grid;
            align-content: center;
            justify-items: center;
        }

        #theme-toggle{
            cursor: pointer;
        }
    </style>
</head>

<body>
    <div>
        <div>
            <!-- 主题切换 -->
            <div id="theme-toggle">
                <!-- 太阳图标 -->
                <svg id="sun" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-sun"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22" ></line></svg>
                <!-- 月亮 -->
                <svg id="moon" style="display: none;" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-moon"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
            </div>
        </div>
    </div>
    <script>
        const themeToggle = document.getElementById("theme-toggle");
        const moonPath = document.getElementById("moon");
        const sunPath = document.getElementById("sun");

        // 为主题切换div添加点击事件
        themeToggle.addEventListener("click", () => {
            if (!isDark()) {
                // 隐藏月亮图标
                moonPath.style.display = "none";
                // 显示太阳图标
                sunPath.style.display = "block";
                // 设置主题为暗色
                document.documentElement.setAttribute("data-theme""dark");
            } else {
                // 显示月亮图标
                moonPath.style.display = "block";
                // 隐藏太阳图标
                sunPath.style.display = "none";
                // 设置主题为亮色
                document.documentElement.setAttribute("data-theme""light");
            }
        });

        // 判断是否为暗色主题
        function isDark() {
            return "dark"==document.documentElement.getAttribute("data-theme")
        }
    </script>
</body>
</html>

实现方式2

另一种思路是html中只定义一套默认变量,然后界面提供主题选择利用javascript进行变量的替换,将替换后的变量标识记录到浏览器的localStorage中,重新进入页面时读取localStorage进行默认切换,后续如有自定义主题的需求也方便扩展,可以利用后端存储主题变量,加载页面时读取列表供用户进行切换及自定义主题。

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>样式设置</title>
    <style>

        /* 定义默认变量 */
        :root {
            --bodyrgba(0000.88);
            --colorrgba(2552552550.88);
        }

        body {
            /* 用变量设置界面背景颜色 */
            background-colorvar(--body);
            /* 用变量设置文字颜色 */
            colorvar(--color);
            margin0;
            height100vh;
            display: grid;
            align-content: center;
            justify-items: center;
        }

        .click{
            cursor: pointer;
        }
    </style>
</head>

<body>
    <div>
        <div>
                <!-- 太阳图标 -->
                <svg class="click" id="sun" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-sun"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22" ></line></svg>
                <!-- 月亮 -->
                <svg class="click" id="moon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-moon"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
            
        </div>
    </div>
    <script>
        const moonPath = document.getElementById("moon");
        const sunPath = document.getElementById("sun");

        // 为月亮图标添加点击事件,切换到暗色
        moonPath.addEventListener("click", () => {
            switchTheme("dark")
        });

        // 为太阳图标添加点击事件,切换到亮色
        sunPath.addEventListener("click", () => {
            switchTheme("light")
        });


        // 支持切换的样式缓存map
        const themeMap ={
            dark: {
                '--body':'rgba(0, 0, 0, 0.88)',
                '--color':'rgba(255, 255, 255, 0.88)',
            },
            light: {
                '--body':'rgba(255, 255, 255, 0.88)',
                '--color':'rgba(0,0,0, 0.88)',
            }
        }

        //  执行切换样式的函数
        function switchTheme(theme) {
            const root = document.querySelector(':root');
            // 获取需要切换的样式对象
            const themePropertys = themeMap[theme];
            // 获取所用对象key
            const keys = Object.keys(themePropertys);
            if(keys.length>0){
                // 循环变更变量属性值
                for (let index = 0; index < keys.length; index++) {
                    const propertyKey = keys[index];
                    root.style.setProperty(propertyKey, themePropertys[propertyKey]);
                }
            }
        }
    </script>
</body>
</html>

好了,娃儿在哭了,我要去带娃,你们去试试吧


原文始发于微信公众号(海之领域):利用css变量实现切换主题的几种方式

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/245671.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!