目录
2. styleSheets Property of document
7. Iterate the Declared CSS Properties
8. Modify CSS Rules Via JavaScript
10. Declared Style VS. Style Property
11. Priority of Declared Style and Style Property
1. How CSS Rules Apply
Every DOM element has an attribute named "style". However, it is not the CSS values that you specified in style section in HTML file. Rather, it's the CSS properties that you can create on fly and manipulate in JavasScript codes.
// CSS
dive#demo {
margin: 5px;
}
// JavaScript
var domElement = document.getElementById("demo");
console.log(domElement.style.margin); // empty string
Although demo has a margin property which value is "5px", we cann't get this value via domElement.style.margin.
There are 2 stages to apply the CSS rules. The first stage is the HTML parsing stage. The second stage is the dynamic stage.
In HTML parsing stage, each style will be read, and each rule in it will be applied automaticlly. And in the dynamic stage, we can alter the CSS values on fly by hand.
In the following sections, we'll dive into how to manipulate both CSS styles specified in the style section in HTML and from style attribute. We'll cover the following properties, classes, and one specific method, one by one:
- styleSheets
- CSSStyleSheet
- CSSRuleList
- CSSRule
- CSSStyleDeclaration
- style
- getComputedStyle
2. styleSheets Property of document
document has a property named styleSheets, which can be used to get all stylesSheets declacred in HTML file.
Suppose we have two styles in a HTML file:
<style>
...
</style>
<style>
div#demo1 {
width: 100px;
height: 100px;
}
div#demo2 {
width: 100px;
height: 100px;
border: 1px solid blue;
}
</style>
Then we can get all of these styles as following:
var styleSheets = document.styleSheets;
console.log(styleSheets.length); // 2
styleSheets is of type StyleSheetList, and each of them is of type CSSStyleSheet.
StyleSheetList has a property length and a method item.
To get the second style, we can also use the '[]' operator, which is more convenient:
var styleSheet = document.styleSheets[1];
3. CSSStyleSheet
CSSStyleSheet has following properties:
- cssRules
- disabled
- href
- media
- ownerNode
- ownerRule
- parentStyleSheet
- rules
- title
- type
To get all rules from the second stylesheet:
var styleSheet = document.styleSheets[1];
var rules = styleSheet.rules;
4. CSSRuleList
rules is of type CSSRuleList. We can iterate each rule like this:
for (var rule of rules) {
console.log(rule);
}
Each rule in the rules is of type CSSRule.
5. CSSRule
CSSRule has 3 important properties:
- cssText
- selectorText
- style
For the first rule above:
div#demo1 {
width: 100px;
height: 100px;
}
The cssText is the whole text presentation of this rule:
div#demo1 { width: 100px; height: 100px; border: 1px solid red; }
As you can see, each rule contains selectors, and many styles in it.
The selectorText is "div#demo1"
, the texts before the "{".
The style is a little bit complicated. It's of type CSSStyleDeclaration.
6. CSSStyleDeclaration
CSSStyleDeclaration has huge default property-value pairs, each property name is a valid CSS term such as "fontSize", "width", etc, and most of them have the default value of empty string.
When we declare property-value pairs in style section, the cssText prpoerty of the rule contains all of these.
var styleSheet = document.styleSheets[1];
var rules = styleSheet.rules;
var rule1 = rules[0];
console.log(rule1.style.cssText); // width: 100px; height: 100px; border: 1px solid red;
And then, various properties are added to the rule. The names of these properties are all numbers, starting from 0.
For example, for the div demo1:
div#demo1 {
width: 100px;
height: 100px;
}
the properties of demo1 would be:
0: "width"
1: "height"
alignContent: ""
alignItems: ""
...
height: "100px"
...
width: "100px"
...
This means the user has declared 2 properties, "width" and "height", and their values are stored in their actual "width" and "height" properties.
7. Iterate the Declared CSS Properties
The following codes:
var styleSheet = document.styleSheets[1];
var rules = styleSheet.rules;
var rule1 = rules[0];
var declaredStyle = rule1.style;
for (var propName in declaredStyle) {
if (propName.match(/^[0-9]/)) {
var value = declaredStyle[propName];
console.log(value + ": " + declaredStyle[value]);
}
}
will yield the output:
width: 100px
height: 100px
If the property name starts with a digit number, then the value of this property is what we declared, so we can get the corresponding CSS value via it.
8. Modify CSS Rules Via JavaScript
We can set the decalred CSS values via JavaScript:
var styleSheet = document.styleSheets[1];
var rules = styleSheet.rules;
var rule1 = rules[0];
var declaredStyle = rule1.style;
declaredStyle.fontSize = "2em";
for (var propName in declaredStyle) {
if (propName.match(/^[0-9]/)) {
var value = declaredStyle[propName];
console.log(propName + ": " + value);
}
}
The result would be:
0: width
1: height
...
19: font-size
...
font-size: "2em"
...
So, the CSS property values we set, whether by declaring in HTML file, or by setting via JavaScript, the property names of which are all recorded in the properties that start with digit number. This is the way the browser uses to distinguish whether they are user defined CSS properties or not.
9. Compound CSS Rules
Let's add a border in div demo1:
div#demo1 {
width: 100px;
height: 100px;
border: 1 solid red;
}
Then, lists the declared property-values as before:
width: 100px
height: 100px
border-top-width: 1px
border-right-width: 1px
border-bottom-width: 1px
border-left-width: 1px
border-top-style: solid
border-right-style: solid
border-bottom-style: solid
border-left-style: solid
border-top-color: blue
border-right-color: blue
border-bottom-color: blue
border-left-color: blue
border-image-source: initial
border-image-slice: initial
border-image-width: initial
border-image-outset: initial
border-image-repeat: initial
The property border is a compound property, which will lead to setting the values for border-top-width, border-top-style, and border-top-color, etc.
10. Declared Style VS. Style Property
Look at the following codes:
var styleSheet = document.styleSheets[1];
var rules = styleSheet.rules;
var rule1 = rules[0];
console.log(rule1.style.width); // "100px"
var domElement = document.getElementById("demo1");
console.log(domElement.style.width); // empty string
We might be supprised to see the diffrence between them. Yes, they are different.
console.log(rule1.style);
console.log(domElement.style);
The rule1.style is as following:
CSSStyleDeclaration:
0: "width"
1: "height"
...
alignContent: ""
alignItems: ""
...
height: "100px"
...
width: "100px"
...
The domElement.style is as following:
CSSStyleDeclaration:
alignContent: ""
alignItems: ""
...
height: ""
...
width: ""
...
Both of them are of type CSSStyleDeclaration, yet they are not the same.
We can change the latter to see more details:
domElement.style.color = "red";
console.log(rule1.style);
console.log(domElement.style);
The first would be left untouched and the latter would be changed:
CSSStyleDeclaration:
0: "width"
1: "height"
...
alignContent: ""
alignItems: ""
...
height: "100px"
...
width: "100px"
...
CSSStyleDeclaration:
0: "color"
...
alignContent: ""
alignItems: ""
...
color: "red"
...
height: ""
...
width: ""
...
Although CSS values are set by various ways, all of these can be combined to yield the final result.
11. Priorities of Declared Style and Style Property
Consider the following codes:
var styleSheet = document.styleSheets[1];
var rules = styleSheet.rules;
var rule1 = rules[0];
var declaredStyle = rule1.style;
var domElement = document.getElementById("demo1");
var propStyle = domElement.style;
declaredStyle.color = "red";
propStyle.color = "blue";
console.log(declaredStyle);
console.log(propStyle);
Which color would the demo1 has, do you think?
Blue? Right. "The blue value is set at last, and thus overrides the value before." you might say so.
Let's switch the order and hava a peek of the result again.
var styleSheet = document.styleSheets[1];
var rules = styleSheet.rules;
var rule1 = rules[0];
var declaredStyle = rule1.style;
var domElement = document.getElementById("demo1");
var propStyle = domElement.style;
propStyle.color = "blue";
declaredStyle.color = "red";
console.log(declaredStyle);
console.log(propStyle);
Even if the red value is set at last, the actual color of the element is blue.
This is because that the style property has a higher priority than the declared style.
12. Get the Final Result
As you can see, there are various ways to set the values of CSS properties. So, where to get the final result?
var styleSheet = document.styleSheets[1];
var rules = styleSheet.rules;
var rule1 = rules[0];
var declaredStyle = rule1.style;
var domElement = document.getElementById("demo1");
var propStyle = domElement.style;
propStyle.color = "blue";
declaredStyle.color = "red";
var computedStyle = window.getComputedStyle(domElement);
console.log(computedStyle);
Well, this CSSStyleDeclaration has 373 properties that start with digit numbers, and all the actual properties have various specific values now.
0: "align-content"
1: "align-items"
...
73: "color"
...
373: "-webkit-user-select"
alignContent: "normal"
alignItems: "noraml"
...
color: "rgb(0, 0, 255)"
...
zoom: "1"
And the value of the property color is "rgb(0, 0, 255)", not "blue" we specified by hand in codes before.
Yes, this is final result after computation of applying all sorts of CSS sources. The last needs to mention is that the CSSStyleDeclaration returned from getComputedStyle is read-only.
13. Conclusion
In this short article, we discussed the declared styles in HTML file and the style property of DOM elements, and the latter requires understanding of objects such as CSSStyleSheet, CSSRule, and CSSStyleDeclaration, etc. We see how these affects the final reuslt. And last, we know how to get the final result.
In short, set the CSS values by writing much in HTML file, modify some of the values via the style property of DOM elements, and check for certainty by invoking of getComputedStyle method.