Skip to content

css自定义属性

2023-04-06
Author:lzugis

自定义属性

基于级联变量的css自定义属性,已经出来很多年了。虽然有less、sass等预处理器大行其道,但是自定义属性也有它的特点和用处,诸如在js中读写、作用域设置等等,在处理UI主题切换等功能上也发挥着很大的作用。

CSS自定义属性(Custom Properties),在一个css选择器内部进行定义,使用两个短横连接线 -- 作为开头命名的名称即被称为自定义属性。

可以给该自定义属性设置任意css属性值。该自定义属性赋值后,将可以作为变量赋值给css样式属性,会立马生效。

定义:--custom-property-name: custom-property-value

css
body {
  /* 声明自定义属性 */
  --bg-color: #f00;
  /* 使用 */
  background-color: var(--bg-color);
}

面的代码,即在body下定义了一个名为--bg-color的自定属性,并设置值为红色的颜色值 #f00。 被body的背景色background-color引用后,则整个页面将会呈现为红色背景。

命名规则

自定义属性的的命名规则,具体的如下:

  • 可以使用数字[0-9]、字母[a-zA-Z]、下划线[_]和短横线[-]组合
  • 可以使用中文等文字字符
  • 不能使用 $、[、^、(、% 等字符
  • 大小写敏感
css
div {
  --1: #0f0;
  --背景: yellow;
  --Fontsize: 20px;
  color: var(--1);
  font-size: var(--Fontsize, 30px);
  background-color: var(--背景);
}

在自定义属性声明的时候,需要给属性赋值,可以使用任意css样式属性值支持的格式。 如 #000、12px、center、字符串、数字等等。

css

{
  --1: #0f0;
  --2: center;
  --f: '测试';
  --n: 22;
  --z: 12px;
}

作用域

css自定义属性存在作用域,即它声明时候所处的css选择器。

  • 当自定义属性属性声明在某个css选择器内的时候,则该选择器的元素和它的所有子元素,都可以使用该自定义属性。
  • 当声明在 :root 下的时候,则全文档范围内皆可使用。

:root 是一个伪类选择器,用来匹配文档的根元素。而在 html 中,根元素即为 <html> 元素,但:root优先级更高,其他则相同。

css
:root {
    --bg-color: #ddd;
    --txt-color: #000;
}
body {
  --bg-color: #f00;
  background-color: var(--bg-color);
  color: var(--txt-color);  
}

如上,:root下定义的可以在任何地方使用,body的背景色是红色。

var()函数

  • var()函数会返回所引用自定义属性对应的值,并被应用到相应的CSS属性上。
  • var()函数只能作为属性的值使用,而且是可以代替样式属性中的值的任何部分。
  • var()函数不能作为属性名、选择器或除属性值外的其他值,如果这样做,只会产生无效语法或无效值。

定义:var(custom-property-name, value)

  • custom-property-name 必需,自定义属性的名称。
  • value 可选,默认回退值。
css
div {
  --1: #0f0;
  --border-color: yellow;
  color: var(--1);
  border: 1px solid var(--border-color);
}
默认值参数
css
div {
  font-size: var(--font-size, 14px);
}

如上,--font-size不存在时,则取默认值14px

不同值的使用情况

用于自定义属性的值

var() 函数变量还能应用于自定义属性声明中,作为值被引用,使用方式一样。

css

div {
  --1: #0f0;
  --背景: var(--1);
  color: var(--1);
  border: 1px solid var(--背景);
}
用于字符串组合

当自定义属性的值是字符串的时候,可以与样式属性值的字符串直接拼接,多用于content属性,如下:

css

:root {
  --wait-copy: ',请复制';
}
div:after {
  content: '正文'var(--wait-copy);
}
用于calc()数字计算

当自定义属性的值是数字的时候,除了可以用于 opacity、z-index等使用数字的css属性以外,还可以使用calc函数进行计算处理。 如下所示:

css

:root {
  --size: 5;
  --width: calc(100px * 5);
}
.div {
  width: var(--width);
  font-size: calc(var(--size) * 10px);
}

在javascript中读写

自定义属性变量,可以通过javascript进行读写,就能很方便的进行操作。 这里主要用到样式对象的 setProperty()getPropertyValue() 方法。

  • 操作全局属性
js
:root {
  --color: red;
}

const root = getComputedStyle(document.documentElement)
// 获取全局属性值
const color1 = root.getPropertyValue('--color').trim()
// 设置属性值
document.documentElement.style.setProperty('--color', 'green')
const color2 = root.getPropertyValue('--color').trim()

console.log(color1, color2) // red green

// 给元素设置样式
const body = document.querySelector('body')
document.querySelector('body').style.backgroundColor = color2
// body的背景色将被设置为绿色
  • 读写元素属性
js
<div id="welc" style="-text-pos: center;">
</div>

// 获取welc元素下定义的属性值,给body设置该值
const welc = document.getElementById('welc')
const align = welc.style.getPropertyValue('--text-pos')
// welc.style.setProperty('--text-pos', 'left')
document.querySelector('body').style.textAlign = align

切换主题

css代码如下:

css
:root {
    --bg-color: #fff;
    --txt-color: #000;
}
body{
    background-color: var(--bg-color);
    color: var(--txt-color);
}

js代码如下:

js
function changeTheme(theme = 'light') {
  const bgColor = theme === 'light' ? '#fff' : '#000';
  const txtColor = theme === 'light' ? '#000' : '#fff';
  document.documentElement.style.setProperty('--bg-color', bgColor)
  document.documentElement.style.setProperty('--txt-color', txtColor)
}

参考资料与更多内容:

  1. MDN CSS变量
  2. 菜鸟教程-CSS变量
  3. CSS自定义属性与前端页面的主题切换