这是我参与8月更文挑战的第1天,活动详情查看: 8月更文挑战
前言
今天在项目中处理一个CSS样式的时候遇到了一个问题:如何用JS去获取CSS自定义属性。一时之间我竟然想不起来怎么用JS去拿到这个属性。
我们知道CSS自定义属性的写法比较特殊,需要两个减号开始(--my-name: red;),那怎么访问它呢??直接style访问??getComputedStyle??--my-name的驼峰命名怎么写??
带着这些疑问开始查资料,写这篇文章来总结一下。
看一个简单的例子:
<html>
<head>
<meta charset="utf-8">
<style>
:root{
--my-val: red;
--in-val: 10px;
}
#ele{
background-color: var(--my-va);
font-weight: 500;
border: 1px solid #ccc;
width: 300px;
float: right;
}
</style>
<link href="test.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="ele"
style="--height-val:200px;height:var(--height-val);border-radius:var(--in-val);text-align: center;">
测试获取CSS属性
</div>
</body>
</html>
外部文件:test.css
#ele {
color: blue;
}
style对象
直接通过style对象去设置和访问样式属性是很常用的一种方式,它返回一个CSSStyleDeclaration对象。
看下边的代码:
window.onload= function() {
let ele = document.getElementById('ele');
//直接使用style访问,需要驼峰命名
console.log(ele.style.height); //var(--height-val)
console.log(ele.style.borderRadius); //var(--in-val)
console.log(ele.style['text-align']); //center
console.log(ele.style.backgroundColor); //不能获取标签内样式
console.log(ele.style.color); //不能获取外部文件样式
console.log(ele.style.cssText);
console.log(ele.style['--height-val']); //不能获取自定义属性
//通过style设置属性
ele.style.width = '200px';
ele.style['line-height'] = '200px';
执行结果如下:

-
style对象只能获取到行内样式(style属性)。
-
如果CSS属性有连字符,则需要用驼峰命名或者中括号来访问。
-
float属性(JavaScript保留字)比较特殊,google可以直接写float,但是IE和火狐无效,IE需要使用styleFloat,非IE可以使用cssFloat访问
-
style对象有一个cssText属性获取了设置在行内的所有样式属性。
-
style对象是无法直接访问自定义属性的。
-
如果样式属性的值是由var函数获取的,则style对象直接将var函数原封不动的返回,不会自己去计算。
-
可以直接通过style对象来设置CSS属性值。
getComputedStyle
getComputedStyle也是比较常用的一个方法,它返回一个CSSStyleDeclaration对象。
语法:
let style = window.getComputedStyle(element, [pseudoElt]);
参数:
- element:必选,要获取样式的元素。
- pseudoElt:可选,伪元素的字符串。必须对普通元素省略或设置为null
看一下用getComputedStyle访问样式属性:
window.onload= function() {
let ele = document.getElementById('ele');
let computedValue = getComputedStyle(ele) || document.defaultView.getComputedStyle(ele);
console.log(computedValue.width); //300px 访问内部样式
console.log(computedValue.borderRadius); //10px 行内样式
console.log(computedValue['text-align']); //center
console.log(computedValue.color); // rgb(0, 0, 255)
console.log(computedValue.backgroundColor); //rgb(255, 0, 0) 返回var函数的计算结果
console.log(computedValue['--height-val']); //undefined 无法访问自定义属性
console.log(computedValue.cssFloat); //right
//只能读不能写
computedValue.width = '200px';
}
执行结果如下:

-
getComputedStyle只支持样式的读取并不支持改写。
-
getComputedStyle获取的样式是浏览器最终渲染效果的样式,包含了内联样式(行内),内部样式(style标签),外部样式(link标签)。
-
与style对象一样,具有连字符的属性需要用驼峰命名或中括号。
-
对于属性值设置为var函数的,getComputedStyle会直接返回var函数的计算结果。
-
一般来说getComputedStyle可以直接通过window对象调用,但是在firefox3.6上访问子框架内的样式时,必须使用document.defaultView.getComputedStyle
-
IE9以下不支持getCoumputedStyle,使用currentStyle对象读取元素的最终显示样式。
getAttribute/setAttribute
getAttribute是一个比较特殊的方法,它返回元素指定的属性值,如果不存在则返回null或空字符串''。
既然是访问元素的属性值,那关css样式有什么关系呢??虽然不能去访问某个具体的样式属性,但是可以访问元素的style属性(行内样式),如果给元素设置了style属性,则返回一个string,否则返回null
getAttribute/setAttribute是一个兼容性比较好的方法,IE的支持度也很好。
let ele = document.getElementById('ele');
//获取元素的style属性
console.log(ele.getAttribute('style'));
//直接设置style
ele.setAttribute('style', 'width: 200px;--hg: 100px;height:var(--hg);');
执行结果如下:

- getAttribute/setAttribute主要是通过元素节点的属性名称来获取元素的属性值,所以可以用该方法可以获取元素节点的style属性值。但是一般不用这个方法来获取和设置样式属性。
- 通过getAttribute获得的style属性的值与style对象的cssText
getPropertyValue
getPropertyValue也可以用来请求css属性的值,但是它不能直接通过元素节点访问,而是作为CSSStyleDeclaration对象的一个方法。所以使用getPropertyValue需要与style对象或者getComputedStyle方法配合使用。
let ele = document.getElementById('ele');
//通过style获取CSSStyleDeclaration对象
let eleStyle = ele.style;
console.log(eleStyle.getPropertyValue('text-align')); //center
console.log(eleStyle.getPropertyValue('height')); //var(--height-val)
console.log(eleStyle.getPropertyValue('--height-val')); //200px
//通过getComputedStyle获取CSSStyleDeclaration对象
let computedValue = getComputedStyle(ele) || document.defaultView.getComputedStyle(ele);
console.log(computedValue.getPropertyValue('background-color')); //rgb(255, 0, 0)
console.log(computedValue.getPropertyValue('color')); //rgb(0, 0, 255)
console.log(computedValue.getPropertyValue('float')); //right
console.log(computedValue.getPropertyValue('--in-val')); //10px
//通过cssRules的style对象来获取CSSStyleDeclaration
let eleDec = document.styleSheets[1].cssRules[0].style;
console.log(eleDec.getPropertyValue('color')); //blue
执行结果:

-
使用getPropertyValue方法,需要先获取CSSStyleDeclaration对象。
-
getPropertyValue方法可以直接访问属性不需要修改属性名称(包括连字符属性和float),不需要对元素属性进行驼峰命名等的转化。
-
getPropertyValue方法可以访问自定义属性。
stylesheets
通过document.stylesheets可以获取CSS样式表。每个CSS样式表中有一个cssRules属性(只读),返回一个CSSRuleList。
加入CSSStyleSheet中的几种常见写法:
- 文档中的<style>和<link>元素
- 使用@import导入的样式
let sheets = document.styleSheets;
for(let i=0; i<sheets.length; i++) {
console.log(sheets);
let ruleList = sheets[i].cssRules;
for(let j=0; j<ruleList.length; j++) {
console.log(ruleList[j]);
console.log(ruleList[j].style);
}
}
执行结果如下:

我们也可以使用insertRule去添加样式规则,stylesheet.insertRule(rule, [, index]);在IE9以下的浏览器中是不支持inserRule的,需要使用addRule方法:addRule(selector,rule,[,index]),具体的细节这里就不多说了。
总结
获取CSS样式属性的方法有很多种,但是CSSStyleDeclaration.getPropertyValue是一种兼容性较好的写法,它不需要转换属性名称,也可以直接访问自定义属性。
最后,发现有时候设置!important好像会失效,看到网上推荐用setProperty,写法:element.style.setProperty(propertyName, value, priority);