Big bold caps-lock TL;DR:
I KNOW HOW SELECTOR SPECIFICITY IS DETERMINED, I THINK IT USES FLAWED ASSUMPTIONS AND I CAN BACK MY IRRITATIONS UP WITH VALID SET THEORY RELATIONS, PLEASE DO NOT RESPOND EXPLAINING W3 CALCULATION RULES FOR SPECIFICITY, PLEASE READ THE QUESTION <- read that.
This has bothered me for some time, when I write a style for some HTML that would be similar to below:
...
<div id="outer">
<span id="inner"></span>
<span></span>
...
</div>
...
Why would specificity rules make the selector "#outer span" more specific than "#inner"?
ID's are unique, so when I say "#inner" I can ONLY be referring to one element, so why is it less specific? I understand the rules on determining specificity, I just wonder if this was intentional or accidental, also if anyone knows how I can ask this question to the people who write the css standards.
I should note, I do understand that I COULD use #outer #inner to ensure maximum specificity, but that seems like it defeats the purpose of ID in the first place. This also is a problematic solution for when I write templates and I'm not sure that one ID will be inside of another. I'm not looking for a workaround, just a theory answer.
My question is theory, entirely based on set logic. The though I have is that if you define a rule for 1 item of n possible items, isn't that as specific as you can go? Why would the creators of CSS selectors make a rule that could define m items of n possible items, where m is a subset of n as a more specific rule?
My thought is that #id would be the equivalent of identifying 1 item by name, and #id elm would be identifying a group by its relation to an item by name. It's completely counter intuitive to call a named item less specific than an unnamed group with a named relation.
I think the idea of "why" is more a "generational" or "authority" view point. If #Parent (of any generation back) says all my children who meet qualification "x" (in your case, span) are going to be given an inheritance of "y" (whatever css property), it doesn't matter what the single individual #Child wants, it needs the authority of the #Parent to get it if the parent has stated otherwise.
Added on edit: The inline style would then be the rebellious child, and the !important the crack down parent. Edit: I kept this for humor, but I don't think it reflects the idea as well as my later statement below.
Added on edit to question in comment: Given:
#outer span ...
#inner (which is a span element)
Then to help insure #inner selection I recommend:
body span#inner (*edit:* just span#inner works *edit:* if defined later)
or give body an id and
#bodyId #inner
Of course, these can still be overridden. The more "generations" involved, the more it becomes difficult to change the behavior because of the generational consensus (if great grandpa and grandpa and parent are all in agreement, it's likely the child is not going to get away with doing his own thing).
I had to majorly rewrite this section on later edit
Given this HTML:
<div id="grandparent">
<div id="parent">
<div id="child"></div>
</div>
</div>
I had previously stated that "#parent div has greater authority than #grandparent div. Both have generational authority, in fact, an 'equal' generational authority, but the first is 'nearer' generation" wins. The error in that is that "nearer" generationally is not what matters, but rather last to be granted authority. Given equal authority powers, the own designated last is the one that wins.
I believe I can still stand by this statement: With that thought in mind, a selector like #child[id] (which outweighs both previous selectors) treats its attributes as permissions for greater authority to rule that which itself controls. Having the # already gave it authority, but not enough to override a # of a earlier generation if that earlier generation also carries another selector granting more authority.
So #grandparent div outweighs #child but not div#child if it is last to receive authority [added this], and not #child[id] because the [id] adds greater authority for the #child to rule itself. If equal selectivity then last one to be granted authority wins.
Again, the style attribute setting a style property itself really acts more like a supreme granting of authority to rule oneself, assuming something more "!important" doesn't take it away.
As a summary statement to answer "why" it is this way (and not in line with "set" theory), I believe it is not about accuracy or really even specificity (though that is the term used) as indeed then one would expect #ChildsName to be the final unique say in the matter because nothing more specific need be said. Rather, however, while the documentation may not state it as such, "selectivity" is really structured on a granting of authority. Who has the most "rights" to rule the element, and given a "tie", who was the last one to be granted those rights.
Because #outer span has both an ID selector and an element selector. That element selector is what makes it weigh more than #inner.
The former means 'select any element found within any element of ID outer'.
The latter means 'select any element with ID of inner'. It doesn't know where #inner is in your HTML document, hence less specificity.
Perhaps you could either try #outer #inner or span#inner try #outer span#inner instead.
How
W3C rules for calculating specificity:
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.
Also, when rules have the same specificity, the last one wins.
Example
outer span: a=0, b=1, c=0, d=1 --> 101
span#inner: a=0, b=1, c=0, d=1 --> 101
div#outer span#inner: a=0, b=2, c=0, d=2 --> 202
Try rearranging rules 1 and 3: http://jsfiddle.net/Wz96w/
Why
My thought is that #inner does not specify a unique element. While it is only 1 element per page, that ID could be a completely different element on another page.
One page:
<div id="outer">
<div id="inner"> ... </div>
</div>
Another page:
<ul id="outer">
<li>main1
<ul id="inner">
<li>sub1</li>
<li>sub2</li>
</ul>
</li>
<li>main2</li>
</ul>
Although, I would not code it this way. I think it explains why adding the element (ul#outer vs. #outer) is worthy of extra specificity.
For the point on descendants, I'm visualizing the DOM for your markup. The rule #outer span has a path length longer than that of #inner. Therefore, in the case, it specifies a more specific subtree, so it should be awarded more specificity (and #outer #inner li should be [is] worth more than #inner li).
To me, and I base this entirely on opinion, it's the expected "natural" behaviour.
Consider this:
You know how CSS specificity is calculated, and from that formula we know that #outer span is more specific than #outer, which is necessary for CSS on the whole to work correctly, and it makes sense. #outer span is also more specific than #inner, which is also logical within the domain of the stylesheet (#inner is only an ID, and #outer span is an ID plus an element, so in order to rank them if we are just looking at the stylesheet, the more qualified one must be more specific).
What's happening here is that you're applying the context of the HTML markup, and saying "Well, that doesn't make sense." To make things work the way that you're expecting, the browser would have to consier the following:
This <span id="inner"> is inside <div id="outer">
The stylesheet rules for #outer span and #inner apply
The rule #outer span is more specific than #inner
But wait! <span id="inner"> is inside <div id="outer">, so ignore the calculations based on the stylesheet and claim that #inner is more specific
That last step makes the determination process entirely based on the structure of the HTML, which makes it impossible to define the specificity in terms of the CSS alone. I personally believe that this would make the entire process more convoluted and hard to define, but you may disagree.
Related
I was just looking at Inspect Element on one of my nested unordered lists and I noticed that one of my selectors with 2 ids is being ranked lower than the selector for a mere list element li. Does this have something to do with the media query that encloses the selector with 2 ids? Or why is this?
What you are seeing is not due to media queries but due to how inheritance is handled in CSS. Take the example below:
#super #specific {
color: blue;
}
p {
color: orange;
}
<div id="super">
<div id="specific">
<p>Paragraph text</p>
<div>Div text</div>
</div>
</div>
Even though you have a style that has a specificity value of 0200, the value of 0001 seemingly overrides it. From what I can tell the reason is due to how CSS calculates the specified value.
According to the spec, it first goes through the cascade to determine any values. If no values found then it will see if anything is inherited. Last it will use any default value for that element. Since the blue color in my example was passed to its inner elements through inheritance, that means that any CSS value applied to the inner elements would override that. It's also why the use of the inherit value in CSS is so important because it allows you to set inheritance as part of the cascade making sure those values take the correct precedence instead of just allowing it to default to it.
What is the difference between these two CSS selectors?
#someId
a#someId
It appears to work like the . selector would. The first selector means "select the element with the ID someID." What does the second one mean? Am I right to think it means "select the a element with ID someID"? Given that there can only be one element with a given ID on a page, what is the purpose behind specifying the tag? Does the second selector get a higher specificity?
Yes, the second selector has higher specificity.
#someId is just a single ID and will select any element with that ID regardless of what element it is. a#someId is both an element and an ID, making it more specific as it will only select anchor a elements with that ID.
There is a common trick to calculating specificity and comparing the specificity of different selectors, which is to count the IDs, classes, and elements like X,X,X. The most specific selector is the one with the highest leftmost number (if that is a tie, move to the next number).
#someId is just an ID, so it's 1,0,0.
a#someId is an ID and an element, so it's 1,0,1 and therefore more specific.
IDs are always more specific than classes and classes are always more specific than elements. Psuedo-elements count as elements and psuedo-classes count as classes for the purposes of calculating specificity. Technically 256 elements = 1 class and 256 classes = 1 ID, but if you ever have that much going on in a selector string you have way bigger problems to worry about.
The only thing more specific than an ID (besides a selector string containing several IDs) is a style with !important or an inline style declared via the style attribute on the element.
More about CSS Specificity:
Specifics on CSS Specificity (CSS Tricks)
CSS Specificity (Smashing Mag)
CSS Specificity (MDN)
Understanding CSS Specificity (Nettuts)
It means,
select an a element having an id someId
Yes, it's more specific.
#someId
Selects the element with the id 'someId'
a#someId
Selects the anchor element with the id 'someId'
The first is the better approach on the assumption you are using unique ids as is recommended, as well as the fact it executes faster (CSS resolves right to left)
This is not a question about being specific enough when ids are included, in which case only the id selector should be used. However, if class name or nesting were present, greater levels of selection helps more accurately target specific elements. However, dont forget that overkill is just as bad as underkill- its all about balance.
The second form a#someId is overkill, as theoretically there should be no two elements with the same id in the document.
One reason I can think of using it would be if you had an element in the page that changed type but maintained the same id through some Javascript manipulation, and you wanted some CSS for that particular ID.
e.g. with some jQuery:
<style>
p#someId { ....}
a#someId { ....}
</style>
<script>
$('#someID').replaceWith( '<a id="someId">Now a link</a>');
</script>
....
<p id='someId'>Not a link</p>
I was wondering what an efficient algorithm would be in the following scenario:
Given a parsed set of css rules, eg.
p.pStyle{margin-bottom:20px;font-family:Arial;}
p{font-family:Verdana;}
p.anotherPStyle{margin-bottom:10px;}
from a css stylesheet, it is possible that several rule sets apply to a given element (say a <p class="pStyle anotherPStyle">hello</p> in my document).
I need to determine what rules in the stylesheet apply to a given element firstly (so here that is p, pStyle and anotherPStyle), and then create a Comparator that is able to sort the applicable rules by specificity (from most-specific to most-general). NOTE: I already have designed an algorithm to apply the rules once sorted so you needn't solve that problem efficiently.
I've been toying with several ideas, namely one that involves determining the level in the DOM tree that a given rule is specific to....Though I'm not sure if this is the correct way to go?
How does the browser engine do this efficiently? I'm looking to replicate it in Java, but am comfortable with many other languages so any code you can offer is most appreciated.
Thanks
That is determined by specificity. In this case, since they are both equally specific, the declaration that comes last in the file, wins.
Specificity Calculation
Specificity is calculated by ranking the different parts of the selector.
Ranked from most specific to least:
Style attribute - If the rule is found in a style attribute, this rank gets 1.
ID - For each ID found in the selector, this rank gets an additional 1.
Classes, Pseudo-Classes, Attribute selectors - For each one found in the selector, this rank gets an additional 1.
Elements - For each element found in the selector, this rank gets an additional 1.
Where rank n > rank n+1, regardless of how many points each rank has.
Example
ul#nav li.active a
The points are:
0 - Not a style attribute.
1 - 1 ID found.
1 - 1 Classname found.
3 - 3 Elements found.
Therefore, each property in that selector has a specificity value of [0,0,1,1,3] (We'll get to that extra zero in a minute). That value is more specific than any selector, as long as it might be, without an ID, for example.
Comparison algorithm:
Go from left to right on the ranks.
Compare the ranks on both selectors.
The rank with the higher amount of point, wins.
If the ranks are equal, continue right to the next (less specific) rank.
If all ranks are equal, the one which comes later in the CSS document, wins.
More important notes:
The universal selector (*) has no specificity value (0,0,0,0) Pseudo-elements (e.g. :first-line) get 0,0,0,1 unlike their
pseudo-class brethren which get 0,0,1,0
The pseudo-class :not() adds no specificity by itself, only what's inside it's parentheses.
The !important directive can be applied on a single declaration, and adds a point to a "0th" rank, which is more specific than anything
else. So in the example above, adding !important on any rule will
bump the specificity value for that rule only to [1,0,1,1,2],
granting it an instant win over any other rules without !important.
Extra Reference
See this great article on the subject
How to determine which styles go to what element
The way the browser does it, is to go over the selector from right to left, and filtering elements out of the DOM as they go.
Going back to the previous example:
ul#nav li.active a
The browser does the following:
Take an a element.
Now check if it has an ancestor that is a li element with an .active class (this is through the descendant combinator: ancestor descendant).
Now check if it has a higher ancestor that is a ul with an ID of #nav (again, the descendant combinator is used).
If all these conditions are met for a certain element, then the styles are applied to it.
You can read it:
Select any a element
with an ancestor with a class of .active, which is also a li,
which in turn has an ancestor with an ID of #nav, which is also a ul.
You'll need to have a fully function and complete DOM tree to be able to successfully determine which element has what CSS styles.
I have a div with an ID:
<div id="main">
What's the correct (or difference) between
div#main {
and
#main {
Regards,
There is a great doco on using efficient CSS selectors, focus on rules with overly qualified selectors:
ID selectors are unique by definition. Including tag or class
qualifiers just adds redundant information that needs to be evaluated
needlessly.
Instead of just applying the style to an element with id main, your selector will re-qualify the element by checking whether or not it's also a div (in that order). To clarify: css selectors are evaluated right to left, unlike same selector syntax when used in jQuery etc.
Re pixelistik's suggestion that div#main is more specific than #main - yes, that is technically correct, however if you have to resort to this to raise a rule's specificity, chances are the structure of CSS you're working on is not as thought through as it should be.
#main matches everything with ID 'main', whereas div#main matches only <div> elements with ID main.
Ideally, you should never have two elements with the same ID, so realistically the two don't make a difference, but there's probably performance related issues regarding whether specifying div makes it find the result faster.
So difference is that:
When you write div#main style will be only for <div> element.
When you write #main it can be used as style for <div>, <span>, <p>, etc.
And what recommend is hard to say, every developer it has it different. So i using for example
span.<nameClass> when is nested in <li> for example.
#nav li span.href a {
...
}
I think it's used when you want that someone class with specific name can have only one element.
So when your write span#href it will works only for <span id="href">Simply dummy text</span> not for others. When you write #href it will works for <span id="href">Simply dummy text</span> or Link but both are correct when you also asking about this. Differences i wrote above.
Both are correct.
div#main is more specific than #main, which means that styles defined with the first selector will override the ones of the second.
Here's a good introduction to CSS specifity:
http://htmldog.com/guides/cssadvanced/specificity/
in some CSS code I found out this type of selector
div#someid
Is this formally correct?
If the answer to (1) is YES, what's the need for the div selector before the #someid, shouldn't the id be unique in a valid web page?
Thanks!
Yes it's correct.
It might be because it makes the selector more specific. The more specific a selector it is the higher priority it is.
It is fine.
The stylesheet might be reused between pages which have the id on different elements
The explicit type provides information for the maintainer about the element
It makes the selector more specific, e.g. to override #other div.
The answer is they are the same but using the div in front of #id is superfluous and removing it does no harm while leaving it in only takes up space. Some may feel it makes the markup more readable, however, since it identifies the type of element the id is associated with.
I did read, once, that placing the div in front of the id may cause the browser to search through all divs first while just using #id does not but I'd have to look up that reference.
From what I understand, CSS will rank selectors based on how specific the selector is, if two rules apply to the same element,
ie
#someId{
color: black;
}
.someClass{
color: green;
}
And you had this div:
<div id="someId" class="someClass">
Then which wins? (There are rules in place to govern this particular example, I believe the ID would win anyway).
But say you had these rules:
.someClass{
color: black;
}
div.someOtherClass{
color: green;
}
Then I the second rule would trump it, because it's more specific.
However as David pointed out, ID's are generally rated a lot higher, so ID will win a lot of the time.
So there are two reasons I can see for using element#id selector
I) It's to trump some convoluted rule, ie div#canvas>div>div#main>div:last-child>div
II) So you know what element it is referring to, ie if your div had and id of "postcodeContainer" and you were trying to find it in the html file, it might be harder because you have to look at every element (unless you used your IDE's search/find option), where as div#postcodeContainer you know you are looking for a div element.
div#someid - select a div with id someid
#someid - select any type of element with id someid
One reason for having the tag selector is that it assumes some basic CSS, like it's a block tag with zero margins/padding.