I have the following html:
<div class="main">
<div class="container">
<h4 class="test"> Test </h4>
</div>
</div>
And the following CSS:
.main .container h4 {
color: red;
}
.test {
color: blue;
}
Why would the class .test not overwrite the color rule? How can I accomplish this?
Thanks
This is a specificity issue.
Specificity is how important a certain selector is. In this case your first declaration uses two classes, and an element. This means only an inline style, #id or something with more classes can over write it.
If you want to affect the class test, we can use .main .container .test, this is 3 classes and will now over write it!
If two things have the same specificity, for example if you use .main .container h4 again, the one that comes last in the document will take precedence.
There is a way to over write regardless of your specificity or where it comes in the document, and that is by adding !important to a certain style, for example .test { color: blue !important; }. This is not recommended if you can use what is described above as this may cause future issues.
The spec can be found here
A selector's specificity is calculated as follows:
count 1 if the declaration is from is a 'style' attribute rather than a rule with a selector, 0 otherwise (= a) (In HTML, values of an element's "style" attribute are style sheet rules. These rules have no selectors, so a=1, b=0, c=0, and d=0.)
count the number of ID attributes in the selector (= b)
count the number of other attributes and pseudo-classes in the selector (= c)
count the number of element names and pseudo-elements in the selector (= d)
The specificity is based only on the form of the selector. In particular, a selector of the form "[id=p33]" is counted as an attribute selector (a=0, b=0, c=1, d=0), even if the id attribute is defined as an "ID" in the source document's DTD.
Concatenating the four numbers a-b-c-d (in a number system with a large base) gives the specificity.
Related
There are numerous questions about the order of loading CSS files and overriding classes, but after reading them I still have something I can't figure out.
There are two CSS files:
<link rel="stylesheet" href="standard.css" type="text/css">
<link rel="stylesheet" href="override.css" type="text/css">
loaded in this order (I checked that).
The HTML looks like this:
<div class="div_D1 ov_D1">
<div class="div_D2 ov_D2">
<div class="div_D3 ov_D3">
blablah
</div>
</div>
</div>
Standard.css contains:
.div_D1{
background: white;
}
.div_D2{
height: 10px;
}
.div_D1 .div_D3{
padding-left: 20px;
}
Override.css contains:
.ov_D1{
background: red;
}
.ov_D2{
height: 50px;
}
.ov_D3{
padding-left: 0px;
}
.ov_D1 and .ov_D2 are applied correctly: the background of .div_D1 is red, the height of .div_D2 is 50px.
.ov_D3 on the other hand does not behave as I expected. If I look at the order the rules are applied, the browser first applies .ov_D3, and then .div_D1 .div_D3, leaving me with an unwanted padding of 20px.
If however I change the class selector in Override.css to
.div_D1 .ov_D3 it does remove the padding.
Also changing the css to
.ov_D3{
padding-left: 0px; !important
}
does the trick. So there are solutions, I only can't understand why with a single selector the order of loading is respected, and with multiple selectors it is not.
This is called specificity of a Selectors. From the book Beginning CSS: Cascading Style Sheets for Web Design, Third Edition by Ian Pouncey and Richard York:
In addition to style sheet precedence, an order of precedence exists for the selectors contained in each style sheet.
This precedence is determined by how specific the selector is.
For example, an ID selector is the most specific,
and the universal selector is the most general. Between these, the
specificity of a selector is calculated using the following formula:
Count 1 if the styles are applied from the (X)HTML style attribute, and 0 otherwise; this becomes variable a.
Count the number of ID attributes in the selector; the sum is variable b.
Count the number of attributes, pseudo-classes, and class names in a selector; the sum is variable c.
Count the number of element names in the selector; this is variable d.
Ignore pseudo-elements.
Now take the four values and put them together in groups of four.
For Example:
Selector : div.someclass.someother
Selector Type : Element Name + Class Name + Class Name
specificity:
0,0,2,1, (a = 0, b = 0,
c = 2, d = 1)
In CSS, there are rules for specificity (quoted from MDN):
The following list of selectors is by increasing specificity:
Universal selectors
Type selectors
Class selectors
Attributes selectors
Pseudo-classes
ID selectors
Inline style
Since you have added specificity to your Selector you weren't able to override by normal CSS class selector.
So your Code
.div_D1 .div_D3is more specific than.div_D3and less specific than.div_D3.ov_D3.
JS Fiddle
As per MDN CSS selectors have rules called 'Specificity' which determine their order of precedence. The more specific a rule is, the greater it's priority regardless of position within a/some stylesheet(s).
A rule such as .class-1 .class-3 has a specificity (it's more specific) higher than .class-3 and takes precedence, as such the less-specific rule cannot override it without the use of !important which negates all other specificity rules. Using the higher specificity rule only takes place with conflicting styles, however.
So, you have set the rule:
.div_D1 .div_D3 { }
The above rule is more specific than:
.ov_D3 { }
Even though they target the same element the rule with the higher specificity takes precedence. You can fix this in your JS Fiddle by prepending the appropriate class structure as defined above.
So, .ov_D3 becomes either:
.div_D1 .ov_D3
or
.ov_D1 .ov_D3
Example here: JS Fiddle
Which class selector rules have a higher specificity for 10 marks?
.A.E.F .C .D
OR
.A .B .C span
HTML:
<div class="A E F">
<div class="B">
<div class="C">
<div class="D">
<span>17590</span>
<span>Points</span>
</div>
</div>
</div>
</div>
CSS:
.A.E.F .C .D /* span */ {
font-size: 1em;
}
.A .B .C span {
font-size: .95em;
}
Here is a JS fiddle demonstrating the issue: http://jsfiddle.net/UgkZY/
I would have thought that the first rule would win. 5 x classes as opposed to 3 x classes + 1 x type. However, the second rule wins out as the .A.E.F appears to only score as 1 class.
If I use the following on-line CSS specificity calculator, http://specificity.keegan.st/, it thinks that the first rule is going to win. In reality, in the Chrome browser, the second one wins.
Can someone clarify that .A.B.C is indeed considered just one class in terms of CSS specificity?
BTW, if I add a span selector to the first rule it will win out.
According to the CSS specification to me it looks like the first one should win.
http://www.w3.org/TR/selectors/#specificity
LI.red.level /* a=0 b=2 c=1 -> specificity = 21 */
Very confusing I must say.
Specificity is only relevant when comparing selectors that match the same element. In this case, your two rules match totally different elements: the first rule matches a div element that contains a class D (div.D), while the second rule matches span elements inside that div.D. What happens then is that both rules apply, but to different elements, resulting in the font size of the span being 95% of that of div.D, which in turn is 100% that of its ancestors. No overruling or overriding of styles takes place.
If you add span to the first rule, this causes it to match the same span elements inside div.D that the second rule also applies to. Only then does specificity come into play: the first rule ends up overriding the second based on counting the class selectors.
Also, .A.B.C counts as three classes; each class selector counts for itself.
Indeed, the second selector wins. It's probably because .A.E.F targets a single element in the HTML tree.
I have a table with some rows:
<table>
<tr class="even"><td>tr0</td></tr>
<tr><td>tr1</td></tr>
<tr class="even"><td>tr2</td></tr>
</table>
I have a CSS rule (rule1) for even rows:
.even{
background-color: blue;
}
I have another rule (rule2) for override the bgcolor of any row:
.override, .override.even{
background-color: green;
}
The weird thing is in IE9 all even rows (with no override class) are green!
Developer tools shows this for even rows:
In these two conditions IE do the job correctly:
If I rewrite rule2 like this:
.override, .override .even{ ... }
If I move rule2 above rule1:
.override, .override.even{ ... }
.even { ... }
Question is what's the difference between .override.even and .override .even?
EDIT:
Thanks for replies. Another question which I forgot to ask is why IE shows the even rows green?
Spacing in between class specifiers means a ascendant -> descendant relationship.
The rule:
.test .heading { font-weight: bold; }
Would apply to the <p> element here:
<span class="test"><p class="heading">Something</p></span>
The lack of space means that the element must have both classes for the rule to apply.
The rule:
.heading.major { color: blue; }
Would apply to the <p> element here:
<p class="heading major">Major heading</p>
Both answers are right, but they don't explain, why IE shows both rows green.
It's because IE has "standard" and "quirks" mode. To make multiple classes selectors work, you need to use proper DOCTYPE at the beginning of the file.
You are in "quirks" mode now and IE don't support multiple selectors, it sees only latest class. So it sees this and rows are green:
.even {
background-color: blue;
}
.override, .even {
background-color: green;
}
Put
<!DOCTYPE html>
(or another DOCTYPE) at the beginning of the file and both rows are going to be blue as expected.
See the W3C [CSS] Selector (Level 3) "Recommendation":
.override .even is two simple selectors separated by a space (which is the descendant combinator, CSS is whitespace-sensitive):
At times, authors may want selectors to describe an element that is the descendant of another element in the document tree (e.g., "an EM element that is contained within an H1 element"). Descendant combinators express such a relationship. A descendant combinator is whitespace that separates two sequences of simple selectors. A selector of the form "A B" represents an element B that is an arbitrary descendant of some ancestor element A.
This selector will match elements that have the class even if and only if there exists an ancestor -- not necessarily the parent! -- element with the class override. (Unlike characters in some movies, an element is never it's own ancestor ;-)
.override.even is a simple selector sequence:
A sequence of simple selectors is a chain of simple selectors that are not separated by a combinator. It always begins with a type selector or a universal selector. No other type selector or universal selector is allowed in the sequence.
A simple selector sequence is evaluated as the conjunction of the individual simple selectors applied to the same element: that is, it will only match elements with both the override and even classes applied.
Happy coding.
.override .even is interpreted as "some element with an 'override' class, with another element with a .even class nested within. It's basically the same as ul li, but applying to CSS classes.
override.even is interpreted as "some single element with BOTH override AND even classes".
<div class="class1">
<div class="class2">
<p>test1</p>
</div>
</div>
If this type coded added than use space between to class like .class1 .class2
<div class="class1 class2">
<p>test2</p>
</div>
If this type coded added than don't use space between to class like .class1.class2
This is Rule 2 of 5 rules the book gives about how the browser determines which rule to apply in a conflict:
An id selector is the second most specific [after inline style attribute]. If there is more than one id in the rule, the rule with greatest number of id selectors wins.
I really don’t understand what Rule 2 is talking about – it says “if there is more than one id in the rule” (which is singular). If there is only one rule, how is there a conflict or comparison(“the rule with greatest… wins”)? How can one rule have a differing number of id selectors, and where is the conflict if there is only one rule?
Can someone please expain this rule thoroughly? Thanks for helping, as I am trying to get the basics of web design down
A selector may have any number of ID selectors.
For example, #id1 #id2 selects the element with the ID id2 if it's a descendant of the element with the ID id1. It has two ID selectors, so it'll be more specific than, say, #id2, which just picks any element as long as it's the one with the ID id2, without any other conditions.
So between these two rules (assuming no inline styles):
#id1 #id2 { color: red; }
#id2 { color: blue; }
The first rule takes precedence, and the text in that element is colored red rather than blue, because the first rule has more ID selectors.
Here is an example, the selector with more id will take precedence:
<div id="parent">
<div id="child">
Some text here
</div>
</div>
now when i apply the css
#parent #child {
background-color: red;
}
#parent div {
background-color: yellow;
}
the selector #parent #child will take precedence. because it is more specific than the second one. in this case the div will have a red background.
I guess this is fairly simple for you but i cant wrap my head around it. I ripped out the important part. I got text inside #content so i cant change it and i dont want to use !important tag.
The css is presented in the order it is placed in my css file.
How come the "#content h2 a, #content h2 a:visited" overrides the .post-header h2 a?
<html>
<head>
.....
</head>
<div id="content">
.....
<div class="post-header">
my text
</div>
</div>
</html>
#content h2 a, #content h2 a:visited {
font-family:"arial black","lucida console",sans-serif;
}
.post-header h2 a {
font-family:Arial,sans-serif;
}
/Joel
First, the browser checks the cascading order. Since the declarations are all for the same media, importance, and origin, the rules are ordered by specificity.
Next, the browser calculates the selector's specificity, and (here's the important part for your question) Id selectors are higher priority than class selectors:
A selector's specificity is calculated
as follows:
count 1 if the declaration is from is a 'style' attribute rather than a rule with a selector, 0
otherwise (= a) (In HTML, values of an element's "style" attribute are style sheet rules. These rules have no selectors, so a=1, b=0, c=0, and d=0.)
count the number of ID attributes in the selector (= b)
count the number of other attributes and pseudo-classes in the selector (= c)
count the number of element names and pseudo-elements in the selector (= d)
The specificity is based only on the
form of the selector. In particular, a
selector of the form "[id=p33]" is
counted as an attribute selector (a=0,
b=0, c=1, d=0), even if the id
attribute is defined as an "ID" in the
source document's DTD.
Concatenating the four numbers a-b-c-d (in a number system with a large base) gives the specificity.
id is more specific than class. In your case you could add the id before the class.
#content .post-header h2 a {
font-family:Arial,sans-serif;
}
You can use the following:
.post-header h2 a {
font-family:Arial,sans-serif!important;
}
To add additional priority to a CSS rule, and ensure that it overrides any others.
Selectors based on ID's take precedent over selectors based on classes.
If you want your class-based style to override the ID selector, append a !important to the element style.
.post-header h2 a {
font-family:Arial,sans-serif !important;
}
!important doesn't work in IE6 though, if you care about those kind of things.