I apply styles to the <html> element and to the <body> element. Is it possible to have the styles on the <html> element apply over the <body's styles?
Applying CSS to <html> doesn't seem to follow the usual rules of CSS specificity. Is this true?
Example: http://jsfiddle.net/59dpy/
Try to make all background colors red.
If you want all of the background red, why add a yellow background to the body? In any case, you just need something more specific.
.test2 { background: red; }
is all you would really need.
Calculating Specificity
The actual specificity of a group of nested selectors takes some calculating. Basically, you give every ID selector (“#whatever”) a value of 100, every class selector (“.whatever”) a value of 10 and every HTML selector (“whatever”) a value of 1. Then you add them all up and hey presto, you have the specificity value.
p has a specificity of 1 (1 HTML selector)
div p has a specificity of 2 (2 HTML selectors, 1+1)
.tree has a specificity of 10 (1 class selector)
div p.tree has a specificity of 12 (2 HTML selectors + a class selector, 1+1+10)
#baobab has a specificity of 100 (1 id selector)
body #content .alternative p has a specificity of 112 (HTML selector + id selector + class
selector + HTML selector, 1+100+10+1)
So if all of these examples were used, div p.tree (with a specificity of 12) would win out
over div p (with a specificity of 2) and body #content .alternative p would win out over all of them, regardless of the order.
Specificity - CSS | MDN
I apply styles to the <html> element and to the <body> element. Is it possible to have the styles on the <html> element apply over the <body>'s styles?
Apply over the body's styles? Not really. In your question, you appear to be confused about CSS's specificity: this defines how different styles compete over the same element when they clash, with the more specific and last defined style winning out.
If html tries to set the background to blue, and html.test tries to set the background to red, the background will be red as that's more specific.
This doesn't apply to child elements
It does not mean those rules then override the childrens' styles. You seem to think that because html.test is more specific a selector than body, the html.test style should also override the body style. That's not the case!
Cascading style sheets don't work that way. Styles only cascade down wherever inheritance applies until a child element overrides that style. The child's style will always win out over its parent's style, and then that will cascade down to its child elements if it's an inherited style (until, again, one of those children overrides it).
Specificity says that out of any competing styles, the most specific one that could apply to the html element wins out. In your provided jsFiddle, there aren't any competing styles, and the html element is now red.
That's it; specificity has no more role to play here. Your body element is then given a background color of yellow. Background colors are not inherited by default, but even if they were, body would not ever inherit its parent's background because you assigned one to it specifically.
You need to apply your styles to the body specifically
In this scenario, you need to either make the body just inherit the html element's style:
body { background-color: inherit; }
Or not give the body a style in the first place.
Or you need to set a specific rule for when the html element has the test class applied:
html.test {
background-color: red;
}
body {
background-color: yellow;
}
html.test > body {
/* Don't have a background color when the HTML should have one
so that the HTML's background can show through. */
background-color: transparent;
}
Related
What is the level of CSS specificity received by inherited properties? I read through the W3 recommendation regarding CSS specificity and so I understand how to calculate the different specificities of css rules which are directly targeting the same element, but I see no mention there of the level of specificity given to inherited attributes.
In particular, the issue I'm encountering has to do with header elements, though I would be very interested to understand this in general.
For example, here's a snippet of HTML:
<h2>This should be black</h2>
<div class="all_red_text">
<h2>This should be red</h2>
</div>
Now if I include some CSS like this:
.all_red_text { color: red; }
I will get the result I expect. On the other hand, if I the css which I included was
h2 { color: black; }
.all_red_text { color: red; }
then all the text will be black. In the first case there is some default browser CSS which is able to be overridden by the inherited property, but then when the same property is manually specified in the second example it takes precedence over the inherited property.
Any declaration that matches element directly will get priority over the property that's inherited from the element's parent. Specificity has nothing to do with that.
CSS is applied to elements in this form:
Priority 1: inline styles
Priority 2: CSS ID styles
Priority 3: CSS class/pseudo-class styles
Priority 4: CSS element styles
Priority 5: Inherited styles
So, using your HTML structure & CSS:
h2 { color: black; }
.all_red_text { color: red; }
<h2>This should be black (and is black)</h2>
<div class="all_red_text">
(This text is indeed red.)
<h2>This should be red (actually, its parent is red - this text is black)</h2>
</div>
The .all_red_text CSS is telling the div.all_red_text element and everything inside it to have red text. The h2 CSS is telling the h2 elements directly to have black text. When the h2 is rendered, it sees "my parent element wants me to have red text, but I'm directly being told to have black text". The same idea applies to further up parents, including the HTML and browser defaults - this allows you to, for example, set the font-family on the html element and have it apply to everything on your (well formatted) web page, unless something specifically overrides it.
If you want the h2 inside div.all_ted_text to also have red text, you'd need to tell those h2 elements directly to have red text; something like this:
.all_red_text h2 { color: red; }
CSS-Tricks has a pretty nice guide on this, although they don't currently go too deep into inherited properties.
There is no such thing as specificity of inherited CSS properties. Selectors, not properties, have specificity.
In your example, both h2 elements match only one of the rules, h2 { color: black; }. Thus, the color of h2 is black (assuming there are no other style sheets that affect the rendering). Anything set on some other elements (including the parent of the second h2 element) does not affect this the least.
If the rule h2 { color: black; } is absent and there are no other rules affecting the situation, then there is no color set on either of the h2 elements. According to the definition of the color property, the value is then inherited from the parent.
Two or more selectors gets engaged into Specificity War, if and only if
they end up targetting the exact same element. However, If two selectors (targetting the same element) have equal specificity weight, then there are other factors like you said, inheritance or the styles getting over ridden in the css file.
I'm new to CSS and want to learn how to make webpages. While learning on Codecademy there was a lesson for classes and Ids which got me confused.
How should the classes be setup and does it make a difference if it's like this
.content h1 {
}
or
h1 .content {
}
Firstly, the spaces in between the CSS selectors .content and h1 matter, meaning, if you are trying to make a CSS rule specifically for h1 elements with a class of content, then the rule needs to be formatted as h1.content.
Secondly, a CSS rule with a space in between selectors (e.g. div .bold) is a combinator known as a descendant selector, and in the example div .bold { font-weight: bold; }, it would mean that any elements with class bold descending from any div element would have a bold font weight style applied.
element.classname mean you are targeting the tag having a class as classname.
element .classname or .classname element mean you are targeting the html element having class classname which is a child/descendent of tag.
What is the level of CSS specificity received by inherited properties? I read through the W3 recommendation regarding CSS specificity and so I understand how to calculate the different specificities of css rules which are directly targeting the same element, but I see no mention there of the level of specificity given to inherited attributes.
In particular, the issue I'm encountering has to do with header elements, though I would be very interested to understand this in general.
For example, here's a snippet of HTML:
<h2>This should be black</h2>
<div class="all_red_text">
<h2>This should be red</h2>
</div>
Now if I include some CSS like this:
.all_red_text { color: red; }
I will get the result I expect. On the other hand, if I the css which I included was
h2 { color: black; }
.all_red_text { color: red; }
then all the text will be black. In the first case there is some default browser CSS which is able to be overridden by the inherited property, but then when the same property is manually specified in the second example it takes precedence over the inherited property.
Any declaration that matches element directly will get priority over the property that's inherited from the element's parent. Specificity has nothing to do with that.
CSS is applied to elements in this form:
Priority 1: inline styles
Priority 2: CSS ID styles
Priority 3: CSS class/pseudo-class styles
Priority 4: CSS element styles
Priority 5: Inherited styles
So, using your HTML structure & CSS:
h2 { color: black; }
.all_red_text { color: red; }
<h2>This should be black (and is black)</h2>
<div class="all_red_text">
(This text is indeed red.)
<h2>This should be red (actually, its parent is red - this text is black)</h2>
</div>
The .all_red_text CSS is telling the div.all_red_text element and everything inside it to have red text. The h2 CSS is telling the h2 elements directly to have black text. When the h2 is rendered, it sees "my parent element wants me to have red text, but I'm directly being told to have black text". The same idea applies to further up parents, including the HTML and browser defaults - this allows you to, for example, set the font-family on the html element and have it apply to everything on your (well formatted) web page, unless something specifically overrides it.
If you want the h2 inside div.all_ted_text to also have red text, you'd need to tell those h2 elements directly to have red text; something like this:
.all_red_text h2 { color: red; }
CSS-Tricks has a pretty nice guide on this, although they don't currently go too deep into inherited properties.
There is no such thing as specificity of inherited CSS properties. Selectors, not properties, have specificity.
In your example, both h2 elements match only one of the rules, h2 { color: black; }. Thus, the color of h2 is black (assuming there are no other style sheets that affect the rendering). Anything set on some other elements (including the parent of the second h2 element) does not affect this the least.
If the rule h2 { color: black; } is absent and there are no other rules affecting the situation, then there is no color set on either of the h2 elements. According to the definition of the color property, the value is then inherited from the parent.
Two or more selectors gets engaged into Specificity War, if and only if
they end up targetting the exact same element. However, If two selectors (targetting the same element) have equal specificity weight, then there are other factors like you said, inheritance or the styles getting over ridden in the css file.
Why in the following code world is blue rather than red?
The specificity of .my_class is 0,0,1,0, but it should inherit the color of #my_id whose specificity is higher at (0,1,0,0).
#my_id {
color: red;
}
.my_class {
color: blue;
}
<p id='my_id'>
Hello
<span class='my_class'>
world
</span>
</p>
See: w3c: 6 Assigning property values, Cascading, and Inheritance - 6.2 Inheritance
An inherited value takes effect for an element only if no other style declaration has been applied directly to the element.
This style applies to an element with id="my_id":
#my_id {
color: red;
}
... and will apply (inherit) to an element nested within having class="my_class" only if its color property is otherwise unspecified.
...which no longer is the case once you declare:
.my_class {
color: blue;
}
The reason this happens is due to inheritance, not specificity.
Look at it this way, if the span didn't have that class, it would inherit the color red from the parent <p> element and "world" would be red. But note that that's due to inheritance.
When you set color for the span, via the class, that overrides the inherited value.
Specificity is for determining which rule to use in multiple competing rules. In your example, there are no competing rules for <span>, so specificity does not come into play. However, if you added this to your styles:
#my_id span {color: orange}
you would see that "world" is orange because of the specificity of the id being more than the class.
It goes based on specificity and location. The class is applied directly to the text, but the ID is further away.
For a long explanation: http://monc.se/kitchen/38/cascading-order-and-inheritance-in-css
A simpler way to think of it, specificity order applies at the same level, if a style is on a parent more local then it applies, regardless of if an ancestor has a style with higher specificity (since it's further away, or less-local).
Go to this page and look at any paragraph's text font size using Firebug. The font size is 13px. Here reset.css body: font-size 100% is overrding master.css body: font-size 62.5%. Why?
My understanding is that if the same tag is defined in two css files, the one that comes last takes precedence. I expected it would use the one from master.css line 10. Don't the the two Body tags have the same specificity?
p takes precedence over body as CSS stands for Cascading Style Sheets
body -> p
#master.css
body {
font-size: 62.5%;
}
#reset.css
body, ..., p {
font-size: 100%;
}
Remove the p element from reset.css and you're fine! You can also give the p element a class or an id and you could also add something like:
#text.css
p.standard {
font-size: 55%;
}
Hope it helps!
What is happening is that the body style defined in reset.css gets overridden by the body style in master.css, but then as you get to individual elements the styling specified by reset.css is more specific and thus a better match for the element and replaces the style defined by master.css for the body.
If you want to have master.css replace the font defined by reset.css, you need to use the same CSS selector, not just the selector for the entire body of the document.