I just found the :root pseudo class.
The :root CSS pseudo-class matches the root element of a tree representing the document. Applied to HTML, :root represents the element and is identical to the selector html, except that its specificity is higher.
https://developer.mozilla.org/en-US/docs/Web/CSS/:root
What exactly is it used for? Why would anyone ever use it aside from higher specificity when you can just use the html selector?
The answer here is:
except that its specificity is higher.
And why does it matter?
In a normal CSS scenario, if you have something like this:
html {
background-color: red;
}
html {
background-color: blue;
}
You will get the blue background, because it's evaluated last. You can see here.
But, if you have this instead:
:root {
background-color: red;
}
html {
background-color: blue;
}
You'll get the red background. You can see here.
Imagine a scenario where you import several libraries and some of then set some properties on the html that you want to get rid of. You can define your properties as !important, you can organize your imports so what you want is evaluated last or you can use the :root selector.
Others Scenarios
As pointed by #user2864740 and #13ruce1337, CSS is not only applied to HTML, but it can be applied to any kind of XML document, including plain XML, SVG and XUL. The :root pseudo class will select the root of other types of document correctly.
Related
In my CSS, I have this:
b {
color: Red;
}
And in my body:
<b>Hello world!</b>
As a result, I get "Hello world!" text that is red in color.
However, as I add more classes:
.myClass {
color: Blue;
}
.green {
color: Green;
}
And I modify my body:
<b>H<a class="myClass">ell</a><a class="green">o</a> wo<a style="color: Black;">rl</a>d
I will not get the same result as earlier.
Is there a way to strictly set a CSS style? Which means that with the above code I wish to get "Hello world!" text that is red.
Thanks
This is a question of CSS Specificicty
The concept: Specificity is the means by which a browser decides which
property values are the most relevant to an element and gets to be
applied. Specificity is only based on the matching rules which are
composed of selectors of different sorts.
Inline styles override external CSS, and class selectors override element level selectors.
The following list of selectors is by increasing specificity:
Universal selectors
Type selectors <--- your b CSS
Class selectors <---- your .xyz CSS
Attributes selectors
Pseudo-classes
ID selectors
Inline style <--- your style=''
If you wish to override specificity, you can use !important after the rule in question, e.g.:
b {
color: Red !important;
}
However, this is not recommended, instead you should write 'better' rules (more specific) to target your HTML as appropriate. This ensures you end up with better structured code, the issue with !important being it can lead to unforeseen circumstances where rules aren't working because you may have forgot you had previously overridden them.
Again, from MDN:
The !important exception
When an !important rule is used on a style declaration, this
declaration overrides any other declaration made in the CSS, wherever
it is in the declaration list. Although, !important has nothing to do
with specificity. Using !important is bad practice because it makes
debugging hard since you break the natural cascading in your
stylesheets.
Some rules of thumb
Never use !important on site-wide css. Only use !important on
page-specific css that overrides site-wide or foreign css (from ExtJs
or YUI for example). Never use !important when you're writing a
plugin/mashup. Always look for a way to use specificity before even
considering !important
With the markup that you provided, no. Otherwise, maybe
The inline style has priority over the stylesheet so part of the text will be black no matter what. You might be able to create a rule that has enough specificity that it will take precendence over any other rules.
b, b .myClass, b .green {
color: red;
}
Though this can get troublesome to maintain. And there is still a chance that a different css rule will get higher precedence later on. I am not completely sure that even specifying all the children with * will do it.
You seem to be asking whether you can set a property (color in the example) on an element in a manner that will not be overridden by settings on inner elements.
You cannot do that with settings on the element itself. But you can set a property on an element and all of its descendants:
b, b * {
color: Red !important;
}
This will override any normal settings for color on inner elements. But it is ineffective against, say, .green { color: Green !important; }. To defeat that, you would need a more specific selector, such as b .green, for your ruleāso there is no general way to achieve that (i.e., a way that is independent of the specific markup used inside the element).
I can't seem to find much information about this.
Smashing Magazine seems to be saying that html and :root are the same thing but surely there must be a tiny difference?
One technical difference between them is that :root - being a pseudo class has a greater specificity than html (a type selector)
:root {
color: red
}
html {
color: green;
}
<div>hello world</div>
So, in the above example, the :root selector overrides the html selector and the text appears red.
From the W3C wiki:
The :root pseudo-class represents an element that is the root of the document. In HTML, this is always the HTML element.
CSS is a general purpose styling language. It can be used with other document types, not only with HTML, it can be used with SVG for example.
From the specification (emphasis mine):
This specification defines Cascading Style Sheets, level 2 revision 1 (CSS 2.1). CSS 2.1 is a style sheet language that allows authors and users to attach style (e.g., fonts and spacing) to structured documents (e.g., HTML documents and XML applications).
For HTML documents, there is no difference - your root element is the <html> tag, so html{} and :root{} are (besides from a difference in specificity) semantically equivalent.
However, you can apply CSS not only to HTML, but all XML-like documents. That's why :root is there - to target the document's root element regardless of document type. Most people are confused by the difference because the overwhelmingly predominant use case for CSS is styling HTML documents.
Example:
You can style SVG documents with CSS. When styling it, your root element will (obviously;-)) not be html but svg. See the following list of SVG tags.
Another thing to consider is that it's technically possible to replace the root element using javascript:
<html>
<body>
<div id=test>
This will become the root element!
<style>
:root { text-decoration: underline; }
html { color: red; } /* this selector will stop working */
</style>
</div>
<button onclick=document.documentElement.replaceWith(test)>click to replace the root</button>
</body>
</html>
in my html I have
<div id="mainNewsBody" class="news">
<a class="readMore" href="/News/Details/1">read more ...</a>
</div>
I tried to style read more ... snipper with this css
#mainNewsBody .news .readMore a{
color: #7F0609;
}
to actually apply this style I have to use !important keyword in color property.
I know that this !important keyword force to use that property but I do not understand why that is the case here, because I explicitly told to match on particular id with particular class element and inside that element to mach link.
Can someone englight me.
Thanks
Try this one:
.news .readMore {
color: #7F0609;
}
There's no need to call for id and class name for the same element.
It's a.readMore instead of .readMore a (the first case would search for an element with class .readMore and append the CSS to any children a-elements)
and #mainNewsBody .news should be #mainNewsBody.news (you should 'concatenate' the id and class since they refer to the same element)
making a total of #mainNewsBody.news a.readMore
Fiddle
EDIT
I see many notes on simplifying your css to just classes. This really depends on what you're trying to accomplish. If you're working with a huge CSS file, I'd recommend specifying as strict as possible. This to prevent any CSS being applied on places where you don't want it to.
a { } for example will mess with all your links, a.news { } will only mess with a class='news'
It'd the specificity which is troubling you, the more elements class id you have in your selector, more specific your selector is.
So for example
.class a {
}
is more specific than just
a {
}
Just see to it that you do not have a more specific selector, if you've than you need to make the current one more specific or use !important declaration as you stated.
In the above snippet this is incorrect
#mainNewsBody .news .readMore a
It will search for an element having class news inside an element having an id mainNewsBody which is not true in your case so either use this
#mainNewsBody a.readMore {
/* This will be more specific than the below one
as you are using id here and not class */
color: #7F0609;
}
Or use
.news a.readMore {
color: #7F0609;
}
Ozan is right, remove the "mainNewsBody" ID from the CSS if it's not absolutely necessary.
.news .readMore a{
color: #7F0609;}
If you want to be really specific and need to include the ID in the CSS selector remove the space from in-front of ".news"
#mainNewsBody.news .readMore a{
color: #7F0609;}
CSS Tricks - Multiple Class ID Selectors
CSS rules marked !important take precedence over later rules. !important ensures that this rule has precedence.
Probably your code is generating inline css for the a element, or you have another less specific definition for a element with !important keyword somewhere else.
Inline styles have priority higher than styles defined outside the element. To overcome the inline style or a style with !important keyword by a less specific definition, you need to define it by the keyword !important and a more specific definition.
I can't seem to find much information about this.
Smashing Magazine seems to be saying that html and :root are the same thing but surely there must be a tiny difference?
One technical difference between them is that :root - being a pseudo class has a greater specificity than html (a type selector)
:root {
color: red
}
html {
color: green;
}
<div>hello world</div>
So, in the above example, the :root selector overrides the html selector and the text appears red.
From the W3C wiki:
The :root pseudo-class represents an element that is the root of the document. In HTML, this is always the HTML element.
CSS is a general purpose styling language. It can be used with other document types, not only with HTML, it can be used with SVG for example.
From the specification (emphasis mine):
This specification defines Cascading Style Sheets, level 2 revision 1 (CSS 2.1). CSS 2.1 is a style sheet language that allows authors and users to attach style (e.g., fonts and spacing) to structured documents (e.g., HTML documents and XML applications).
For HTML documents, there is no difference - your root element is the <html> tag, so html{} and :root{} are (besides from a difference in specificity) semantically equivalent.
However, you can apply CSS not only to HTML, but all XML-like documents. That's why :root is there - to target the document's root element regardless of document type. Most people are confused by the difference because the overwhelmingly predominant use case for CSS is styling HTML documents.
Example:
You can style SVG documents with CSS. When styling it, your root element will (obviously;-)) not be html but svg. See the following list of SVG tags.
Another thing to consider is that it's technically possible to replace the root element using javascript:
<html>
<body>
<div id=test>
This will become the root element!
<style>
:root { text-decoration: underline; }
html { color: red; } /* this selector will stop working */
</style>
</div>
<button onclick=document.documentElement.replaceWith(test)>click to replace the root</button>
</body>
</html>
How is it possible to override styles specified in another style sheet?
I do not want to use the !important tag to override them. I would much rather specify a new style sheet, put styles in there. Could this be achieved by changing the load order of the style sheets?
It depends. CSS stands for Cascading Style Sheets, and there's a specific order that styles are applied in, overwriting previous styles. Without going into too much detail:
If your rules have the same specificity, just load your stylesheet second and everything will work fine.
If your rules have higher specificity, the order won't matter.
If your rules have lower specificity, you'll need to modify them to match.
So, what's specificity? Basically, it's the sum of each selector in a rule. So this:
a {
background-color: black;
color: white;
}
Has less specificity than this:
body a {
color: orange;
}
ID selectors have higher specificity than class selectors, which have the same specificity as pseudo-class selectors, which have higher specificity than tag selectors. So if all your content is contained in a <div> with an id of content, you would be able to override a style that looks like this:
body a {
border: 0;
}
With:
#content a {
border: 1px solid black;
}
The boostrap stylesheet should be loaded first, your stylesheet second, this way your overwrites will be picked up.
This is called "cascading", from the documentation:
Cascading
This is the capability provided by some style sheet languages such as CSS to allow style information from several sources to be blended
together. These could be, for instance, corporate style guidelines,
styles common to a group of documents, and styles specific to a single
document. By storing these separately, style sheets can be reused,
simplifying authoring and making more effective use of network
caching. The cascade defines an ordered sequence of style sheets where
rules in later sheets have greater precedence than earlier ones. Not
all style sheet languages support cascading.
If you can increase the specificity of styles, you can do this without the !important.
For example:
HTML
<div id="selector">
<a>Hello</a>
<a class="specific">Hi</a>
</div>
CSS
div a {}
Will be ignored, if you give a specific class inside #selector
.specific { }
Here is a demo explaining my point. Basically, the idea is to define the styles as closely as possible.
look at http://www.stuffandnonsense.co.uk/archives/css_specificity_wars.html.
<p class="example">
This is a <strong>test</strong>.
</p>
strong { color: red; }
p strong { color: green; }
p.example strong { color: blue; }
The text will be blue. The order of the rules doesn't matter.