I have a CSS stylesheet that contains a lot of declarations starting with html.some-class. Now I'm wondering if there would be any difference if I wrote :root.some-class.
I suppose that the browser may scan the whole DOM to try to apply the html.some-class rule, because there might be an invalid document with more than one <html> tag. On the other hand, in a valid HTML document (and I can be sure that the styled document is standard-compliant) there is only one root element, so that the :root search doesn't have to traverse the whole tree.
Taking the above into consideration, would my stylesheet be more efficiently applied if I used :root instead of html?
Footnote: I'm not able to get rid of the selector targeting the <html> tag.
Related
What is the point to define global CSS custom properties in a :root instead of body or html tags. Is this will lead to different effects or perfomance issues?
Well, it might be weird in the first place, but it is nothing about it except specificity. :root is actually html itself with a higher specificity, so the main reason for putting variables in :root element is because we are not only using them in CSS but we are using them in SVG and XML also. So we may call :root global scope as its usage. You can also read more about their actual difference here.
It lets you to define various variables and use them if needed. _root stands for html element - have you ever attached style for hrml tag?
Performance - wouldn't bother...
I have two different pages/nodes on a site that I want to have different #page rules for background-image in my CSS. I'm not very familiar working with print-rules in particular (though I work daily with CSS), therefore I'm not sure how to accomplish this
I've tried to put #page with the likes of body.node-type #page{} but that does nothing. Is this even possible, or is #page impossible to pair with a class or id – in that case, how do I solve this?
Edit, tried below but didn't work either:
body.node-type-reference{
#page {
}
}
I'm aware that I maybe could put the background image in a separate div, but that would require major rework of the code and I'm not even sure if that'd play nice when overflowing to the second page (since the first page is unique from the rest in both node-types).
You won't be able to do this within the #page at-rule alone. CSS does not support conditional #page at-rules with conditions that depend on matching selectors within the markup.
As you've found, this is worked around by including the specific #page at-rule in a <style> embedded in just the page you want the rule to apply (given that the class you're matching is on the body element, which is usually indicative of document-specific styles).
I noticed that if I place <style> inside <body> the css would be applied to all elements after and before <style> tag.
So it looks to me that the css is processed when the page is loaded, similar behavior to javascript document ready event. Am I right? And if that is the case in which order would multiple <style> tags be processed?
TL;DR:
In short, the answer to your question is: once a <style> tag is met inside <body> everything stops and the CSSOM is being rebuilt and re-applied to all existing rendered (painted) content.
Placing <style> tags inside <body> is considered bad practice because it can create FOUC. But if your <style> tag only contains rules for elements placed after it in DOM, placing it in body is perfectly fine, as no FOUC can happen.
The render process of a page is quite complex. But, overly-simplified, here's what happens
<head> is read and CSSOM is built. All CSS is render blocking, unless explicitly specified otherwise by use of #media queries. The non-blocking CSS is still loaded, it's not entirely skipped.
DOM building and CSSOM building are ran in paralel, but all <script> execution is deferred until CSSOM has been built (on </head> tag met), at which point all loaded <script>s are ran, blocking DOM building. JS can make changes to CSSOM at this point. *
Placing <style> tags inside <body> interrupts everything (JS execution and DOM building), CSSOM is being updated and applied to the already rendered content, if any. Everything is resumed after.
* On further testing it appears <head> parsing is single threaded. CSSOM building does block javascript execution but it's done is stages, as each <link /> and <style> tags are met (a <script> placed after a <link> will only execute after the <link /> was resolved and applied to CSSOM). <script> tags placed in between CSS resources are not deferred until all CSS resources in <head> are parsed, as I initially thought.
And, of course js can make changes to CSSOM at run time. See this question I asked for more on how js execution is blocked by CSSOM building.
All the above apply to the normal loading, without considering async, which adds a whole new layer of complexity to it.
If you're interested in more details, I recommend going through the Performance chapter of Web Fundamentals, provided by Google.
Scope of CSS
A style element applies to the whole document, regardless of its position. It is applied as soon as it's loaded.
Reason for putting style tags in <body>
Since every browser has a limited number of threads for downloading a page's files (like JS, CSS, images and asynchronously loaded HTML, JSON or XML), people tend to include CSS files at the end of the body element instead of the classic approach of including them in the head element. This way the rest of the page can be loaded and rendered, and the styling is applied last. You would go this way if your CSS is purely for the looks (i.e. no required element hiding) in order to improve the user experience.
CSS files vs style rules in HTML
Including an external CSS file or putting the same rules in a style element have equivalent results regarding layout and styling. The external file has the downside of a little HTTP overhead, but the benefit of being cached for any further request. If your site consists of more than one page, you usually want to have one or more CSS files that are downloaded only once and re-used for most pages. In addition you can have page-specific rules in another file or within the HTML page.
So it looks to me that the css is processed when the page is loaded, similar behavior to javascript document ready event. Am I right?
No. The stylesheet is modified with the new CSS code when that code is added to the DOM. There's no delay until the rest of the DOM has finished loading. If there was you'd see a FOUC.
which order would multiple <style> tags be processed?
The order they appear in. Then the normal rules of the cascade apply.
About to have an exam and I am going through the previous exam that we have been given.
The question:
When two or more style sheet rules apply to the same element, which of the following types of rules will take precedence?
a. Any declaration with browser origin
b. Normal declaration with user origin
c. Normal declaration with author origin
d. Document-level declaration
So would the answer be c or d? I am guessing d because c is a normal declaration and not important but I can't really get a definitive answer anywhere
Cheers
The answer is Document-level declaration, it will be applying styles to the element which are declared in the last linked stylesheet
Test case
HTML
<html>
<head>
<link href="stylesheet1.css" rel="stylesheet" type="text/css" />
<link href="stylesheet2.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div>hello<!-- Color applied will be green --></div>
</body>
</html>
CSS
stylesheet1.css
div {
color: red;
}
stylesheet2.css
div {
color: green;
}
The exam question is incorrect, as exam questions often are. The expression “Document-level declaration” is not a proper term, and it has multiple interpretations. Moreover, it uses the word “normal” without specifying its meaning, but probably you are right in guessing that it means “without !important”.
The answer is “undecided”, since “a” includes a browser style sheet rule with !important, which trumps “b” and “c” (and “d” unless it means something that may have !important), but it would be incorrect to say that “a” generally trumps the others. Edit: The specifications might be read so that browser style sheets cannot have !important or that it does not have an effect in them, but at least Firefox html.css uses !important (obscurely).
My bet is that the author of the exam did not think of the possible of an !important rule in a browser style sheet, and you are therefore supposed to answer “c”.
Edit: Option “d” is there probably just to confuse students, since if it means a style sheet embedded in an HTML document, it’s a special case of author style sheel, and being embedded does not affect the cascade rules (among style sheets embedded with style and linked with link, it is the placement of the HTML element that matters, not the embedded vs. linked thing).
You are reffering the CSS Cascading.
So, from the link
Style sheets may have three different origins: author, user, and user agent.
and the precedence between them is as follows
By default, rules in author style sheets have more weight than rules in user style sheets. Precedence is reversed, > however, for "!important" rules. All user and author rules have more weight than rules in the UA's default style
sheet.
The cascading order is defined by ascending order of precedence
user agent declarations
user normal declarations
author normal declarations
author important declarations
user important declarations
The CSS specificity Rules later come into picture.
I'm setting up an image cluster for a webpage (similar to sprite-map) for performance reasons. I have a utility that generates the master image, and css to reference the image map.
For simplicity sake, I'd rather include the new css after the regular css file, instead of writing a script to search and replace all the classes in the original css. Something like so in the html (psuedo code):
<LINK href="normal.css" rel="stylesheet" type="text/css">
if(%=usingImageCluster=%)
<LINK href="master.css" rel="stylesheet" type="text/css">
So all the styles that are defined in normal.css would get overridden by the new styles in master.css.
Couple of questions:
Besides the "duplication" of information, does this override cause performance issues?
Will the browser still pull the non-clustered images, because the original CSS file is still included (negating the positive performance gains of image clustering)?
Is there a guarantee that the last loaded style will always be the one applied?
Besides the "duplication" of information, does this override cause performance issues?
Yes, you are generating a new HTTP request for the second external stylesheet. Too many HTTP requests is the #1 slowdown factor for most webpages.
Will the browser still pull the non-clustered images, because the original CSS file is still included (negating the positive performance gains of image clustering)?
Yes, the browser will pull ALL images from the first and second CSS file. Performance time will increase almost linearly (approximate). Especially if you are rewriting every css selector, or changing lots of images.
Is there a guarantee that the last loaded style will always be the one applied?
Yes. Unless the first sheet uses !important on certain style attributes, the last declared styles for a selector will always be applied. This is where Cascading Style Sheets get their name.