Skip to content

网页 「明亮/暗黑」

TIP

css 变量、hsl(hue, saturation, lightness)hsla(hue, saturation, lightness, alpha)在在明/暗主题切换上起到了事半功倍的效果。参考地址:how-to-use-variables-in-css
hsl 参数含义「Saturation can range from 0% to 100%, where 0% is gray and 100% is the full color. Lightness can also range from 0% to 100%, where 0% is black, 100% is white, and 50% is the normal color.」

1. 改变根元素属性 :root[theme="dark"]

默认主题

css
:root {
  --background-primary: hsl(193, 78%, 91%);
  --text-primary: hsl(25, 76%, 10%);
  --button-primary-bg: hsl(214, 77%, 10%);
  --button-text-primary: hsl(214, 77%, 98%);
}

暗黑主题

css
:root[theme="dark"] {
  --background-primary: hsl(25, 76%, 10%);
  --text-primary: hsl(34, 78%, 91%);
  --button-primary-bg: hsl(214, 77%, 98%);
  --button-text-primary: hsl(214, 77%, 10%);
  /* filter: invert(1) brightness(0.6); */
}

用 JS 切换主题

js
document.querySelector("#toggle-theme").addEventListener("click", (e) => {
  console.log("Switching theme");
  if (document.documentElement.hasAttribute("theme")) {
    document.documentElement.removeAttribute("theme");
  } else {
    document.documentElement.setAttribute("theme", "dark");
  }
});

Demo1

Custom Properties and Color Palettes

Custom properties work especially well for managing HSL color palettes. HSL stands for hue, saturation, lightness. It’s a light-based color model that’s similar to RGB. We can use HSL values in CSS thanks to the hsl() and hsla() color functions. The hsl() function accepts three arguments: hue, saturation, and lightness. The hlsa() function also accepts a fourth argument, indicating the color’s alpha transparency (a value between 0 and 1).

While an RGB system expresses color as proportions of red, green, and blue, HSL uses a color circle where hue is a degree position on that circle, and the tone or shade are defined using saturation and lightness values. Saturation can range from 0% to 100%, where 0% is gray and 100% is the full color. Lightness can also range from 0% to 100%, where 0% is black, 100% is white, and 50% is the normal color.

2. @media screen and (prefers-color-scheme: dark)

prefers-color-scheme CSS 媒体特性用于检测用户是否有将系统的主题色设置为亮色或者暗色。(考虑兼容性)

CSS 媒体查询动态设置相关 css 变量

css
@media (prefers-color-scheme: light) {
  :root {
    --background-primary: hsl(193, 78%, 91%);
    --text-primary: hsl(25, 76%, 10%);
    --button-primary-bg: hsl(214, 77%, 10%);
    --button-text-primary: hsl(214, 77%, 98%);
  }
}

@media (prefers-color-scheme: dark) {
  :root {
    --background-primary: hsl(25, 76%, 10%);
    --text-primary: hsl(34, 78%, 91%);
    --button-primary-bg: hsl(214, 77%, 98%);
    --button-text-primary: hsl(214, 77%, 10%);
  }
}

通过 js 监听系统主题变化

js
window
  .matchMedia("(prefers-color-scheme: dark)")
  .addEventListener("change", (event) => {
    if (event.matches) {
      console.log("dark mode");
    } else {
      console.log("light mode");
    }
  });

Demo2

Custom Properties and Color Palettes

Custom properties work especially well for managing HSL color palettes. HSL stands for hue, saturation, lightness. It’s a light-based color model that’s similar to RGB. We can use HSL values in CSS thanks to the hsl() and hsla() color functions. The hsl() function accepts three arguments: hue, saturation, and lightness. The hlsa() function also accepts a fourth argument, indicating the color’s alpha transparency (a value between 0 and 1).

While an RGB system expresses color as proportions of red, green, and blue, HSL uses a color circle where hue is a degree position on that circle, and the tone or shade are defined using saturation and lightness values. Saturation can range from 0% to 100%, where 0% is gray and 100% is the full color. Lightness can also range from 0% to 100%, where 0% is black, 100% is white, and 50% is the normal color.

3.强兼容性的主题切换方案

结合 1 和 2,去掉@media (prefers-color-scheme: dark)相关css代码,在监听到prefers-color-scheme变化时,处理「主题切换按钮」和其他相关逻辑,来实现「用户主动」和「自动响应系统」同时兼容的主题切换。

css
:root {
  --background-primary: hsl(193, 78%, 91%);
  --text-primary: hsl(25, 76%, 10%);
  --button-primary-bg: hsl(214, 77%, 10%);
  --button-text-primary: hsl(214, 77%, 98%);
}

/* 主动:响应用户切换 */
:root[theme="dark"] {
  --background-primary: hsl(25, 76%, 10%);
  --text-primary: hsl(34, 78%, 91%);
  --button-primary-bg: hsl(214, 77%, 98%);
  --button-text-primary: hsl(214, 77%, 10%);
  /* filter: invert(1) brightness(0.6); */
}
js
/**用户主动切换主题 */
const switchMode = (e) => {
  console.log("Switching theme");
  if (document.documentElement.hasAttribute("theme")) {
    document.documentElement.removeAttribute("theme");
  } else {
    document.documentElement.setAttribute("theme", "dark");
  }
};

/**首次检测(生效一次):系统主题是否时夜间(暗黑)主题 */
const preference = localStorage.getItem("vitepress-theme-appearance") || "";
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
if (
  !preference || preference === "auto" ? prefersDark : preference === "dark"
) {
  document.documentElement.setAttribute("theme", "dark");
}

/**持续监听:系统主题是否时夜间(暗黑)主题 */
window
  .matchMedia("(prefers-color-scheme: dark)")
  .addEventListener("change", (event) => {
    if (event.matches) {
      console.log("dark mode");
      document.documentElement.setAttribute("theme", "dark");
    } else {
      console.log("light mode");
      document.documentElement.removeAttribute("theme");
    }
  });

Demo:Mixed

Custom Properties and Color Palettes

Custom properties work especially well for managing HSL color palettes. HSL stands for hue, saturation, lightness. It’s a light-based color model that’s similar to RGB. We can use HSL values in CSS thanks to the hsl() and hsla() color functions. The hsl() function accepts three arguments: hue, saturation, and lightness. The hlsa() function also accepts a fourth argument, indicating the color’s alpha transparency (a value between 0 and 1).

While an RGB system expresses color as proportions of red, green, and blue, HSL uses a color circle where hue is a degree position on that circle, and the tone or shade are defined using saturation and lightness values. Saturation can range from 0% to 100%, where 0% is gray and 100% is the full color. Lightness can also range from 0% to 100%, where 0% is black, 100% is white, and 50% is the normal color.

4. 自定义属性

document.body.style.setProperty('--bg-home', 'whitesmoke');

设置自定义属性:

js
document.body.style.setProperty("--bg-home", "whitesmoke");

使用自定义属性:var()

js
document.body.style.backgroundColor = "var(--bg-home)";

移除自定义属性:

js
document.body.style.removeProperty("--bg-home");

Released under the MIT License.