本站主题切换功能:CSS变量,让JS与CSS互通有无

CSS变量简介

CSS变量的定义及使用如下,可定义的类型非常广泛。

/* 声明 */
--VAR_NAME: <声明值>;
/* 使用 */
var(--VAR_NAME)

/* 根元素选择器(全局作用域),例如 <html> */
:root {
  /* CSS 变量声明 */
  --main-color: #ff00ff;
  --main-bg: rgb(200, 255, 255);
  --logo-border-color: rebeccapurple;

  --header-height: 68px;
  --content-padding: 10px 20px;

  --base-line-height: 1.428571429;
  --transition-duration: .35s;
  --external-link: "external link";
  --margin-top: calc(2vh + 20px);
}

body {
  /* 使用变量 */
  color: var(--main-color);
}

与 SASS、LESS预处理器变量的编译时处理不同,CSS 变量由浏览器在运行时处理,这使得它们更加强大和灵活。

CSS 到 JS

在 CSS 变量出现之前,将值从 CSS 传递到 JS 非常困难,甚至需要一些 hack 技巧。现在有了 CSS 变量,可以直接通过 JS 访问变量值并进行修改。

// 定义 CSS 变量
.breakpoints-data {
  --phone: 480px;
  --tablet: 800px;
}
const breakpointsData = document.querySelector('.breakpoints-data');

// 获取 CSS 变量的值
const phone = getComputedStyle(breakpointsData)
    .getPropertyValue('--phone');

// 设置 CSS 变量的新值
breakpointsData.style
    .setProperty('--phone', 'custom');

本站重构后,也合理的利用了CSS变量,但方式更加灵活。

比如本站的主题切换功能,白天与夜晚主题。在根节点root中使用多个变量组,使用不同的元素选择器进行分组。然后通过js更改元素的class类或者属性对主题进行切换。

:root {
    --wp--preset--font-size--normal: 16px;
    --wp--preset--font-size--huge: 42px;
}
:root {
    --my-preset-line-height-1: 1.8;
    --my-preset-letter-spacing-1: .04em;
    --my-preset-color-font-1: #444444;
    --my-preset-color-font-2: #333333;
    --my-preset-color-font-3: #000000;
    --my-preset-color-bg-1: #ffffff;
    --my-preset-color-bg-2: #fbfbfb;
    --my-preset-color-bg-3: #1f1e2c;
    --my-preset-color-alert-bg: #ffffff;
    --my-preset-color-button-bg-1: #ffffff;
    --my-preset-color-button-font-1: #f96b4d;
    --my-preset-color-button-bg-active: #f96b4d;
    --my-preset-color-active: #f96b4d;
    --my-preset-color-active-hover: #f5ad6e;
    --my-preset-color-font-gray-1: #9f9f9f;
    --my-preset-color-font-gray-2: #cdcdcd;
    --my-preset-color-font-gray-3: #888888;
    --my-preset-color-border-1: #d8d8d8;
    --my-preset-color-border-2: #cccccc;
    --my-preset-color-border-3: #eeeeee;
    --my-preset-color-bg-gray-1: #f8f8f8;
    --my-preset-color-bg-gray-2: #fbfbfb;
    --my-font-family-1: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Hiragino Sans GB, Microsoft YaHei UI, Microsoft YaHei, Source Han Sans CN, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
    --my-font-family-2: NotoSerifSC, "Microsoft Yahei", 宋体, sans-serif;
    --my-font-family-3: 'Helvetica', 'Microsoft Yahei', '冬青黑体简体中文 w3', 微软雅黑, 'Tahoma', 'Arial', 'SimSun';
    --my-preset-color-scrollbar-thumb: #d2d2d2;
    --my-preset-color-scrollbar-track: rgba(51, 51, 51, 0.1);
}
[data-user-color-scheme='dark'] {
    --my-preset-color-bg-1: #1f1e2c;
    --my-preset-color-bg-2: #1a1927;
    --my-preset-color-bg-3: #0b0b10;
    --my-preset-color-alert-bg: #262631;
    --my-preset-color-font-1: #d5d5d5;
    --my-preset-color-font-2: #f5f5f5;
    --my-preset-color-font-3: #ffffff;
    --my-preset-color-border-3: #3f3d55;
    --my-preset-color-button-bg-1: #f96b4d;
    --my-preset-color-button-bg-active: #f5ad6e;
    --my-preset-color-button-font-1: #f5f5f5;
    --my-preset-color-bg-gray-1: #2e2d3b;
    --my-preset-color-font-gray-3: #a9a9a9;
    --my-preset-color-border-2: #aaaaaa;
    --my-preset-color-scrollbar-thumb: #3b3b5f;
    --my-preset-color-scrollbar-track: #1f1e2c;
}
export default {
  template,
  setup() {
    const colorScheme = ref(window.localStorage.getItem('user-color-scheme') || "light");
    const setColorScheme = (scheme) => {
      colorScheme.value = scheme;
      document.documentElement.setAttribute('data-user-color-scheme', scheme);
      window.localStorage.setItem('user-color-scheme', scheme);
    };

    return { colorScheme, setColorScheme };
  },
};

除此之外还有很多 css 原生能力,比如:Mixins、运算符等。

加载中...
加载中...