Grouped Class Selectors and CSS Specificity - css

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.

Related

Specificity rules for comma delineated lists

When using Cascading Style Sheets I have observed the order of specificity as follows:
1st Laws: In-line Styles
2nd Laws: Number of ID Selectors
3rd Laws: Number of Class Selectors
4th Laws: Number of Element Selectors
So, items with in-line styles came first, followed by declarations with one or more ID selectors, followed by declarations with one or more class selectors, followed by declarations with one or more element selectors. With more IDs, classes and elements meaning more precedence, respectively.
From this viewpoint I was unable to comprehend where comma delineated lists of IDs, classes or elements fit. Does a comma delineated list have any special precedence rules? Also, in a single comma delineated list, are IDs, classes and elements considered separate items, for the purposes of calculating specificity?
Code example:
html, body, header {
position: absolute;
top: 0px;
}
header {
position: relative;
top: 50px;
}
What takes precedence in the above example? Is the comma delineated list treated as referencing a single element, in which case the header would take precedence simply for being last in the cascade, or is the comma delineated list treated as multiple elements, and therefore takes precedence? Or are there other rules I should be considering first?
Does a comma delineated list have any special precedence rules?
Strictly speaking, a selector-list does not have its own specificity value, but for the purposes of the cascade, the specificity of a selector-list is equal to the specificity of the most specific selector that matches the element. This is not stated explicitly in the current specification, but it appears in selectors-4. Even so, since a selector-list is nothing more than a way to combine two or more selectors in a single expression without having to repeat their style declarations, it makes sense why it would work this way.
Remember that a selector is only relevant to an element when it matches the element — otherwise, it never enters into specificity calculations, or any part of the cascade.
Also, in a single comma delineated list, are IDs, classes and elements considered separate items, for the purposes of calculating specificity?
Every simple selector has its own specificity value, but these values are added up at the complex-selector level. A complex selector is one part of a selector-list. For example, the selector-list
.foo > .bar, nav input:checked + label
has two complex selectors:
.foo > .bar, with a specificity of (0, 2, 0)
nav input:checked + label, with a specificity of (0, 1, 3)
What takes precedence in the above example? Is the comma delineated list treated as referencing a single element, in which case the header would take precedence simply for being last in the cascade, or is the comma delineated list treated as multiple elements, and therefore takes precedence?
In your example, the selector-list html, body, header consists of three separate lone type selectors. Since every element can only be of one element type at a time, it's easy to deduce that all three selectors in the list are mutually exclusive, i.e. an element can only match one of any of the three selectors at a time (or none at all). A header element can never match the html or body selectors, and so neither of those selectors is relevant. You just have the header selector to deal with, and specificity becomes less of an issue in your example. The result is that your second rule, with just the header selector, takes precedence, because the only two selectors that are relevant are equally specific.
But this becomes more pertinent when you have a selector-list that consists of more than one selector that can match the same element. Let's pretend that both selectors in my example above can match the same label element. So we have two selectors of specificity (0, 2, 0) and (0, 1, 3) that both match the same element. As in the first paragraph of my answer, the specificity is equal to that of the most specific selector, (0, 2, 0). It is not, as one might otherwise have guessed, the total specificity of all matching selectors (0, 3, 3), or the specificity of the least specific (which wouldn't really make sense anyway).
This means, for example, that a separate rule with a selector whose specificity is (0, 3, 0) will still take precedence over the selector-list, even if both selectors in that list match the same element. Consider this contrived example (you'll rarely find examples of this in the wild):
.foo > .bar.baz {
color: red;
}
.foo > .bar, nav input:checked + label {
color: blue;
}
<nav class="foo">
<input type="checkbox" id="check" checked>
<label for="check" class="bar baz">Checkbox</label>
</nav>
Notice that regardless of whether the checkbox is checked, the label never turns blue. This is because .foo > .bar.baz has a specificity of (0, 3, 0) which is higher than each of the two individual specificities given above, even though it's lower than the combined specificity, since specificities are never combined this way.
Remember that CSS is cascading - meaning the style that is referenced FURTHER down a CSS file will take precedence assuming the selector is the same:
header {
background-color: red;
}
p, span, header {
background-color: yellow;
}
<header>
HEADER
</header>
If we switch around the declarations above, the opposite happens:
p, span, header {
background-color: yellow;
}
header {
background-color: red;
}
<header>
HEADER
</header>
As you can see, comma separated selectors / declaration make no difference - they're treated the same as if you'd done them singly.
In CSS separating rules by , means listing multiple selectors. So html, body, header style will be applied to every html, body and header no matter if some of it is missing or not. It will not provide any precedence to selector.
In your example header position will be absolute just because first rule will have lower precedence than second. Same as:
header {
position: relative;
}
header {
position: absolute;
}
I this case both of them are Element Selectors so the outputted css would be bottom one because css is rendered from top to bottom precedence in this case takes last element.

Overriding combined css classes

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

Overwrite rules of h4 with a class selector

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.

What's the difference between `.class1.class2` and `.class1 .class2` CSS rule?

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

Question about a confusing css specificity rule, (from the book SAMS Teach Yourself CSS in 24 Hours Second Ed.)

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.

Resources