1. 多种换肤模式

    实现网页换肤功能的网站
    (图片来源网络,侵删)
    • 浅色模式:默认的经典设计。
    • 深色模式:护眼的暗色主题。
    • 自动模式:根据用户系统偏好自动切换。
    • 自定义模式:允许用户自由选择主色调和背景色。
  2. 流畅的切换动画:使用 CSS 过渡效果,让主题切换更加平滑自然。

  3. 主题持久化:使用 localStorage 保存用户的主题选择,刷新页面后不会丢失。

  4. 响应式设计:网站在各种设备上都能良好显示。

  5. 清晰的代码注释:让你能轻松理解实现原理。

    实现网页换肤功能的网站
    (图片来源网络,侵删)

最终效果预览


实现步骤

我们将整个项目分为三个文件:

  1. index.html:网页的结构和内容。
  2. style.css:所有主题的样式,以及切换动画。
  3. script.js:处理主题切换的逻辑。

第 1 步:HTML 结构 (index.html)

这个文件定义了网站的骨架,它包含一个主题切换器(一组按钮)和网站的主要内容区域。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">网页换肤功能演示</title>
    <link rel="stylesheet" href="style.css">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700&display=swap" rel="stylesheet">
</head>
<body class="theme-light">
    <header>
        <h1>网页换肤功能演示</h1>
        <p>探索不同的主题模式,找到你最喜欢的设计风格。</p>
    </header>
    <main>
        <section class="theme-switcher">
            <h2>选择主题</h2>
            <div class="theme-buttons">
                <button class="theme-btn" data-theme="light">
                    <span class="theme-icon">☀️</span>
                    <span class="theme-name">浅色</span>
                </button>
                <button class="theme-btn" data-theme="dark">
                    <span class="theme-icon">🌙</span>
                    <span class="theme-name">深色</span>
                </button>
                <button class="theme-btn" data-theme="auto">
                    <span class="theme-icon">🌗</span>
                    <span class="theme-name">自动</span>
                </button>
            </div>
        </section>
        <section class="content-card">
            <h2>这是内容卡片</h2>
            <p>这段文字的颜色和背景会根据你选择的主题而改变,这得益于我们使用了 CSS 自定义属性(变量),让主题切换变得非常简单和高效。</p>
            <div class="card-actions">
                <button class="card-button">主要操作</button>
                <button class="card-button secondary">次要操作</button>
            </div>
        </section>
        <section class="content-card">
            <h2>另一个示例卡片</h2>
            <p>你可以轻松地扩展这个系统,创建更多的主题,森林绿”、“海洋蓝”或者“日落橙”,只需要在 CSS 中定义新的变量集合即可。</p>
            <ul>
                <li>列表项 1</li>
                <li>列表项 2</li>
                <li>列表项 3</li>
            </ul>
        </section>
    </main>
    <footer>
        <p>&copy; 2025 换肤功能演示. 使用 CSS 变量和 JavaScript 构建。</p>
    </footer>
    <script src="script.js"></script>
</body>
</html>

第 2 步:CSS 样式 (style.css)

这是实现换肤的核心,我们使用 CSS 自定义属性(CSS Variables) 来定义颜色,这使得我们只需要通过修改 body 元素的类名,就可以改变整个网站的颜色方案。

/* --- 基础样式和重置 --- */
:root {
    /* 默认浅色主题的变量 */
    --bg-primary: #ffffff;
    --bg-secondary: #f4f4f9;
    --text-primary: #333333;
    --text-secondary: #666666;
    --accent-color: #007bff;
    --border-color: #e0e0e0;
    --card-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    --transition-speed: 0.3s;
}
/* 全局过渡效果,让颜色变化平滑 */
*,
*::before,
*::after {
    box-sizing: border-box;
    transition: background-color var(--transition-speed),
                color var(--transition-speed),
                border-color var(--transition-speed);
}
body {
    font-family: 'Noto Sans SC', sans-serif;
    margin: 0;
    padding: 0;
    background-color: var(--bg-primary);
    color: var(--text-primary);
    line-height: 1.6;
}
h1, h2 {
    color: var(--text-primary);
}
header {
    text-align: center;
    padding: 2rem;
    background-color: var(--bg-secondary);
}
main {
    max-width: 800px;
    margin: 2rem auto;
    padding: 0 1rem;
}
/* --- 主题切换器样式 --- */
.theme-switcher {
    text-align: center;
    margin-bottom: 2rem;
}
.theme-buttons {
    display: flex;
    justify-content: center;
    gap: 1rem;
    margin-top: 1rem;
}
.theme-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    border: 2px solid var(--border-color);
    background-color: var(--bg-primary);
    color: var(--text-primary);
    border-radius: 12px;
    cursor: pointer;
    font-size: 1rem;
    font-weight: 500;
    transition: transform 0.2s, box-shadow 0.2s;
}
.theme-btn:hover {
    transform: translateY(-3px);
    box-shadow: var(--card-shadow);
}
.theme-btn.active {
    border-color: var(--accent-color);
    background-color: var(--accent-color);
    color: white;
}
.theme-icon {
    font-size: 1.5rem;
    margin-bottom: 0.5rem;
}
/* --- 内容卡片样式 --- */
.content-card {
    background-color: var(--bg-primary);
    border: 1px solid var(--border-color);
    border-radius: 12px;
    padding: 1.5rem;
    margin-bottom: 1.5rem;
    box-shadow: var(--card-shadow);
}
.content-card h2 {
    margin-top: 0;
}
.card-actions {
    display: flex;
    gap: 1rem;
    margin-top: 1rem;
}
.card-button {
    padding: 0.7rem 1.5rem;
    border: none;
    border-radius: 8px;
    font-weight: 500;
    cursor: pointer;
    transition: background-color 0.2s;
}
.card-button.primary {
    background-color: var(--accent-color);
    color: white;
}
.card-button.secondary {
    background-color: var(--bg-secondary);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
}
footer {
    text-align: center;
    padding: 1.5rem;
    margin-top: 2rem;
    color: var(--text-secondary);
    background-color: var(--bg-secondary);
}
/* --- 深色主题变量 --- */
body.theme-dark {
    --bg-primary: #121212;
    --bg-secondary: #1e1e1e;
    --text-primary: #f0f0f0;
    --text-secondary: #b0b0b0;
    --accent-color: #4a9eff;
    --border-color: #333333;
    --card-shadow: 0 4px 6px rgba(0, 0, 0, 0.5);
}
/* --- 自动主题的媒体查询 --- */
/* 当系统设置为深色模式时,自动应用深色主题 */
@media (prefers-color-scheme: dark) {
    body.theme-auto {
        --bg-primary: #121212;
        --bg-secondary: #1e1e1e;
        --text-primary: #f0f0f0;
        --text-secondary: #b0b0b0;
        --accent-color: #4a9eff;
        --border-color: #333333;
        --card-shadow: 0 4px 6px rgba(0, 0, 0, 0.5);
    }
}
/* 响应式设计 */
@media (max-width: 600px) {
    .theme-buttons {
        flex-direction: column;
        align-items: center;
    }
    .card-actions {
        flex-direction: column;
    }
}

第 3 步:JavaScript 逻辑 (script.js)

这个脚本负责处理用户的点击事件,修改 body 的类名,并保存用户的偏好。

实现网页换肤功能的网站
(图片来源网络,侵删)
document.addEventListener('DOMContentLoaded', () => {
    // 1. 获取所有主题按钮
    const themeButtons = document.querySelectorAll('.theme-btn');
    // 2. 从 localStorage 获取保存的主题,如果没有则使用 'auto' 作为默认值
    const savedTheme = localStorage.getItem('theme') || 'auto';
    // 3. 页面加载时,应用保存的主题
    document.body.className = `theme-${savedTheme}`;
    updateActiveButton(savedTheme);
    // 4. 为每个主题按钮添加点击事件监听器
    themeButtons.forEach(button => {
        button.addEventListener('click', () => {
            const selectedTheme = button.getAttribute('data-theme');
            // 更新 body 的类名
            document.body.className = `theme-${selectedTheme}`;
            // 更新活动按钮的样式
            updateActiveButton(selectedTheme);
            // 将用户选择的主题保存到 localStorage
            localStorage.setItem('theme', selectedTheme);
        });
    });
    /**
     * 更新主题按钮的激活状态
     * @param {string} activeTheme - 当前激活的主题名称
     */
    function updateActiveButton(activeTheme) {
        themeButtons.forEach(button => {
            if (button.getAttribute('data-theme') === activeTheme) {
                button.classList.add('active');
            } else {
                button.classList.remove('active');
            }
        });
    }
    // 可选:监听系统主题变化,当用户选择 'auto' 时动态切换
    // 注意:这个功能需要页面加载时已经是 'auto' 模式才有效
    window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
        if (document.body.classList.contains('theme-auto')) {
            // 这里不需要手动切换,因为 CSS 的媒体查询会自动处理
            // 但我们可以在这里添加一些逻辑,比如通知用户系统主题已改变
            console.log('系统主题已更改为:', e.matches ? '深色' : '浅色');
        }
    });
});

如何运行

  1. 创建文件:在你的电脑上创建一个名为 theme-demo 的文件夹,然后在其中创建 index.htmlstyle.cssscript.js 三个文件。
  2. 复制代码:将上面提供的代码分别粘贴到对应的文件中。
  3. 打开浏览器:用 Chrome、Firefox 或 Edge 等现代浏览器打开 index.html 文件。
  4. 体验功能:点击“浅色”、“深色”和“自动”按钮,观察网站的变化,刷新页面,你会发现你选择的主题被保留了。

核心技术点总结

  1. CSS 自定义属性 (变量):这是实现换肤的关键,将颜色定义为变量(如 --bg-primary),然后在需要的地方使用 var(--bg-primary) 引用,切换主题时,只需改变这些变量的值。
  2. HTML Class 切换:通过 JavaScript 修改 body 的类名(如 theme-light, theme-dark),来加载不同的 CSS 变量集合。
  3. localStorage:用于在客户端持久化存储用户的主题偏好,即使用户关闭了浏览器或刷新了页面,设置依然有效。
  4. prefers-color-scheme:这是一个强大的 CSS 媒体查询,可以检测用户的操作系统是否设置了深色模式,是实现“自动模式”的基础。
  5. 平滑过渡 (transition):为颜色相关的属性添加过渡效果,能让用户体验更加流畅和愉悦。

这个实现方案既简单又强大,是现代 Web 开发中实现换肤功能的标准做法,你可以基于这个框架,轻松地扩展出更多、更复杂的主题。