Say you have an external stylesheet (<link>
), followed by a <script>
. Is the external stylesheet always applied before the <script>
executes, so that getComputedStyle
always respects the external stylesheet's rules?
Or are browsers allowed to run JavaScript before earlier stylesheets have been applied?
Example:
<!doctype html>
<html>
<head>
<link href="/my-stylesheet.css" rel="stylesheet" />
</head>
<body>
<div id="foo"></div>
<script>
window.getComputedStyle(document.getElementById('foo')).width
// => "200px" due to stylesheet - is this reliable?
</script>
</body>
</html>
Definition and Usage. The getComputedStyle() method gets all the actual (computed) CSS property and values of the specified element. The computed style is the style actually used in displaying the element, after "stylings" from multiple sources have been applied. Style sources can include: internal style sheets, external style sheets,...
Would be easier. If you want make sure that an external stylesheet has loaded, then you can use the window load event which will fire when page resources such as external stylesheets and images have finished loading and the page also will have its final layout:
The computed style is the style actually used in displaying the element, after "stylings" from multiple sources have been applied. Style sources can include: internal style sheets, external style sheets, inherited styles and browser default styles.
However, if the styles need to be applied across multiple documents, you should link to an external style sheet instead of using individual embedded style sheets. Using embedded stylesheets holds a distinct advantage over inline styles which only allow you to address one HTML element at a time.
In short: YES this is reliable.
To prove I created following testserver based on nodejs:
Directory:
/testserver.js
/server/index.js
/server/style.js
testserver.js
creates a node js server and ensures, that each request takes two seconds to load:
var express = require('express');
var app = express();
app.listen(8888);
app.use(function(req,res,next){
setTimeout(next, 2000);
});
app.use(express.static('./server'));
My index.html
:
<html>
<head>
<link href="style.css" rel="stylesheet" />
</head>
<body>
<div id="mydiv"></div>
<script>
console.log(window.getComputedStyle(document.getElementById('mydiv')).width);
</script>
</body>
</html>
My style.css
#mydiv {
position: absolute;
background: #ff0000;
height: 10px;
width: 100px;
}
Now I test it by starting my server and calling http://localhost:8888/index.html
In the Chrome developer tools the timeline looks like this:
As you can see the index.html
file loads before style.css
And the Javascript Console outputs 100px
as expected:
Because of the fact, that there are no errors in js-console and the only output is the expected 100px
I proved that the adoption in question is true.
EDIT: Now I tested more: This works on Chrome with 2s, 5s and 60s => Works! Furthermore I tested it on Firefox, Opera and Safari with 2s. => Works!
Sorry I've got no IE available.
EDIT 2: I just did more research:
The behaviour I figured out is defined by W3C. A loading style file is blocking script execution when it was defined by link
-tag or style
-tag:
A style sheet in the context of the Document of an HTML parser or XML parser is said to be a style sheet that is blocking scripts if the element was created by that Document's parser, and the element is either a style element or a link element that was an external resource link that contributes to the styling processing model when the element was created by the parser, and the element's style sheet was enabled when the element was created by the parser, and the element's style sheet ready flag is not yet set, and, the last time the event loop reached step 1, the element was in that Document, and the user agent hasn't given up on that particular style sheet yet. A user agent may give up on a style sheet at any time.
Note: Giving up on a style sheet before the style sheet loads, if the style sheet eventually does still load, means that the script might end up operating with incorrect information. For example, if a style sheet sets the color of an element to green, but a script that inspects the resulting style is executed before the sheet is loaded, the script will find that the element is black (or whatever the default color is), and might thus make poor choices (e.g. deciding to use black as the color elsewhere on the page, instead of green). Implementors have to balance the likelihood of a script using incorrect information with the performance impact of doing nothing while waiting for a slow network request to finish.
W3C Blocking Scripts
And as defined in this document, in the parsing process the script will not execute until the blocking style has been loaded.
If you want make sure that an external stylesheet has loaded, then you can use the window load
event which will fire when page resources such as external stylesheets and images have finished loading and the page also will have its final layout:
window.addEventListener('load', function() {
window.getComputedStyle(document.getElementById('foo')).width
});
You can also devise a test to see if the stylesheet has already been loaded by putting a specific and unique style rule in the stylesheet that applies to a specific DOM element (which could even be hidden) and then you can get that style with getComputedStyle()
and see if it matches what it should be. If so, then the stylesheet has been loaded. If not, then the stylesheet has not yet been loaded. But, if you still need to wait until it's loaded, the the window load
event is what you would want to use.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With