Logically (at least to me), the more specific #allSteps should override the drilldown to the generic UL, but it doesn't work like that in any browser I've tried it in.

The reason I'm asking is our organization is starting to make heavy use of LESS and I need to be armed with very specific warnings to pass around so I don't end up doing a lot of cleanup afterwards (which seems to be my job lately)

TechnoBear
—
2011-10-28T15:54:34Z —
#2

As Paul is not on-line at present, and I was reading about specificity last night, I'll hazard an answer and hope it's right.

As I understand it, the first rule wins out because it consists of three id selectors - #advertiser, #centerContentContainer and #edit_listing (plus two element selectors td and ul) - whereas the second one only has one id selector - #allSteps.

I agree that the second one seems more specific to a human, but apparently it isn't to a CSS parser. Three id selectors win out over one, because there are more specifics in the string (i.e. three of them). I'm not sure I've explained that too well. (:

Inline styles are considered more specific than anything else, followed by id selectors, then class selectors, then element selectors. If two rules both have the same type of selector, then the one with more instances of that type will win out.

I think that's right. No doubt Paul will correct me if it isn't.

DaveMaxwell
—
2011-10-28T16:08:07Z —
#3

I'm coming to learn that, though from a conceptual standpoint, I'm still having a hard time grasping why. If a specific element (ID) can be applied, then it should override a cascading style (i.e. styles which match generically per a parent relationship).

A co-worker linked me to this page which explains the same thing in an entertaining way (yes, I'm a geek like that)

TechnoBear
—
2011-10-28T16:15:39Z —
#4

DaveMaxwell said:

I'm coming to learn that, though from a conceptual standpoint, I'm still having a hard time grasping why. If a specific element (ID) can be applied, then it should override a cascading style (i.e. styles which match generically per a parent relationship).

I agree, but I'm also coming to learn that you can't make a computer see sense by arguing with it. :headbang:

DaveMaxwell said:

A co-worker linked me to this page which explains the same thing in an entertaining way (yes, I'm a geek like that)

Brilliant. The book I was reading has that same link, but when I tried it yesterday, I got a 404. I assumed, as the book is a couple of years old, that the page no longer exists. Thank you - I'm off for a read.

DaveMaxwell
—
2011-10-28T16:19:22Z —
#5

TechnoBear said:

I agree, but I'm also coming to learn that you can't make a computer see sense by arguing with it. :headbang:

Too true - too often, I'm expecting it to do what I want it to do instead of what I tell it to do. This time I'm trying to get it to do what I tell it to do (which for once is the same thing)

TechnoBear said:

Brilliant. The book I was reading has that same link, but when I tried it yesterday, I got a 404. I assumed, as the book is a couple of years old, that the page no longer exists. Thank you - I'm off for a read.

Sorry, I'm late to the party but I think you covered most bases however I will explain also As an aside you should read my entry in the reference as I go into great detail on this subject (I often have to re-read it myself)

DaveMaxwell said:

I'm coming to learn that, though from a conceptual standpoint, I'm still having a hard time grasping why. If a specific element (ID) can be applied, then it should override a cascading style (i.e. styles which match generically per a parent relationship).

I think you are misconstruing the meaning of specificity in css terms and an element is not more specific if the id is closer to it. When IDs have the same weight and specificity then those later in the in the stylesheet will win out - it makes no difference where the ids/classes are in the html.

In the above CSS both rules have the same weight but the rule that comes later in the stylesheet will win out. It doesn't matter that #test2 is closer to the element concerned as this has no bearing on the outcome. If the ids were html order dependent then that would destroy the separation between presentation and content in some respects as you would lose control from the stylesheet.

Reverse the css order above but don't change the html and you will see that the background colour will change.

A co-worker linked me to this page which explains the same thing in an entertaining way (yes, I'm a geek like that)

I saw that years ago and although its a good stab at making it easier to digest I think it actually confuses the issue more and is also inaccurate as Eric Meyer point out.

Here’s a simplified description of the process by which the specificity of the selectors of two or more declarations is compared:

1) If one declaration is from a style attribute, rather than a rule with a selector (an inline style), it has the highest specificity. If none of the declarations are inline, proceed to step two.

2) Count the ID selectors. The declaration with the highest count has the highest specificity. If two or more have the same number of ID selectors, or they all have zero ID selectors, proceed to step three.

3) Count the class selectors (for example, .test), attribute selectors (for example, [type="submit"]), and pseudo-classes (for example, :hover). The declaration with the highest total has the highest specificity. If two or more have the same total, or they all have totals of zero, proceed to step four.

4) Count the element type selectors (for example div) and pseudo-elements (for example, :first-letter). The declaration with the highest total has the highest specificity.

If two or more selectors have the same specificity, then, according to the rules of the CSS cascade, the latter specified rule takes precedence.

So you can see that the more ids (classes/selectors) you add to your list the more weight the rule has and other rules have to be at least equal (and follow later in the stylesheet) or have even more weight to win out.

As ids are unique there is seldom a need to have more than one id in a rule and generally the only time you would have two ids is if you are trying to be more specific.

DaveMaxwell
—
2011-10-28T17:53:29Z —
#8

Paul_O_B said:

Sorry, I'm late to the party but I think you covered most bases however I will explain also As an aside you should read my entry in the reference as I go into great detail on this subject (I often have to re-read it myself)

Actually, I did read that - I still didn't understand why my problem was occurring.

Paul_O_B said:

I think you are misconstruing the meaning of specificity in css terms and an element is not more specific if the id is closer to it. When IDs have the same weight and specificity then those later in the in the stylesheet will win out - it makes no difference where the ids/classes are in the html.

Perhaps I am, but in the case I'm citing, the id wasn't closer, it was on the element itself. That's why I was confused as to why that style didn't have more weight than the ul style.

Take your example, Paul. I've added a test3 to your html, and tweaked your css. I would expect to see the red background because it's on the element itself, but it's blue.

As ids are unique there is seldom a need to have more than one id in a rule and generally the only time you would have two ids is if you are trying to be more specific.

Agreed - it's one of the pitfalls of using LESS - you have to be MUCH more diligent on how you place your styles to ensure you don't end up with more specificity (did you ever try to say that word?) than you intended to....

PaulOB
—
2011-10-28T18:48:38Z —
#9

DaveMaxwell said:

Perhaps I am, but in the case I'm citing, the id wasn't closer, it was on the element itself. That's why I was confused as to why that style didn't have more weight than the ul style.

Take your example, Paul. I've added a test3 to your html, and tweaked your css. I would expect to see the red background because it's on the element itself, but it's blue.

As I said it doesn't matter if the id is closer or even on the element itself because rules with more weight will always win out. In your example even "#test p" would win out over #test3. A rule that is specific to an element can be far way in the html or as close as you like. The one with the most weight always wins out. Every time you add something to the rule you are adding more weight based on the tables I linked to above.

That's all you really need to know about it. If the path is longer and they are both using ids then the longer path wins out. If there is a mixture of ids classes and selectors then you need to refer to the table above and work out which is the heaviest. For example if one has 1 id only and the other on has 500 classes the the rule with all the classes will never win out because ids carry more weight than any number of classes. If both have classes only then the the one with the most classes wins out and so on for type selectors. Or a mixture of all the above. (Ignoring user styles with important and normal rules with important as they have special rules also.)

Therefore you can look at a stylesheet and without even looking at the html or knowing anything about the html you can predict exactly which rule will be applied (assuming valid rules for that element) as the position in the html is unimportant.

DaveMaxwell
—
2011-10-28T19:05:43Z —
#10

Thanks, Paul.

Like I said, it doesn't make sense to me that something applied directly to an element can get overridden by the "generic" base on the parents (guess that's the programmer in me), but I know I need to re-configure my understanding of it, and more importantly, re-configure my co-workers understanding as we're making more and more use of LESS (personally, I'd rather use less LESS and more straight css) and these situations are going to come up more and more.

PaulOB
—
2011-10-28T19:45:18Z —
#11

DaveMaxwell said:

Thanks, Paul.

Like I said, it doesn't make sense to me that something applied directly to an element can get overridden by the "generic" base on the parents (guess that's the programmer in me), but I know I need to re-configure my understanding of it, and more importantly, re-configure my co-workers understanding as we're making more and more use of LESS (personally, I'd rather use less LESS and more straight css) and these situations are going to come up more and more.

You see, I never had this problem (Well maybe just a little)

All elements have rules applied to them - (whether you like it or not). These rules can come from far and near and through a process of conflict resolution you end up with styles applied to that element. Some styles are from UA styles, some styles may be from user stylesheets some styles are from author stylesheets and some styles are inherited from the parent's styles.

I think you may be confusing inheritance with specificity a little as inheritance has nothing to do with specificity really. A child will inherit certain properties from its parent should no more specific styles apply. If for example you set a div to have a font-size of 40px then its children will inherit that 40px font size unless there were more specific rules.

In the above the p element would have a font-size of 13px because rules that apply specifically to the p element are only the simple class called .not40. The heavyweight id selectors are targeting the parent div and not the p element. Remove the class from the p element and the p element will then inherit the font-size from the parent div. Alternatively change the first rule to say "#test #test2 p" and then that rule will win out. It seems to me that this is what you are confusing with rules that actually apply specifically to that element.

The C in CCS is not called cascading for nothing.:) Unlike scripting it's an amalgamation of rules that finally style the element and those styles could be a combination of rules from many sources.

Stevie_D
—
2011-10-28T20:08:57Z —
#12

DaveMaxwell said:

Perhaps I am, but in the case I'm citing, the id wasn't closer, it was on the element itself. That's why I was confused as to why that style didn't have more weight than the ul style.

The way I see it, in simple terms, is that both "[yadda yadda] ul" and "#allsteps" are directly targeting <ul id="allsteps">, so it isn't down to inheritance or anything else, it's just a fight to the specificity (and yes, I can say it!).

As TechnoBear said in #2, "[yadda yadda] ul" has three IDs, whereas "#allsteps" only has one. Therefore "[yadda yadda] ul" is more specific than "#allsteps". If one rule has more IDs than another, it wins, end of story, game over.

This does raise the question as to why you need "#advertiser #centerContentContainer #edit_listing td ul". Surely "#edit_listing td ul" would be just as good? Of course, you'd still need "#edit_listing td ul#allsteps" to beat it, but it's easier CSS, as well as being less processor intensive to parse.

Kind of off-topic here, but about a year ago I almost completely stopped using ids, using classes instead. It has made my style sheets a lot simpler, as classes are a lot easier to override than ids and have a lot more uses. I basically reserve ids for JS and on-page links now.

PS Unless I missed it above, CSS does offer !important as an escape clause, though I've never actually resorted to it. E.g.

#allSteps { margin-left: 0 !important}

felgall
—
2011-10-29T04:22:46Z —
#16

ralph_m said:

as classes are a lot easier to override than ids and have a lot more uses.

Actually ids have a lot more uses than classes.

In HTML you can link to an id - you can't link to a class. <a href="#here">jump</a> links to <p id="here"> In JavaScript all browsers support getElementById but only some of the more modern ones support getElementsByClass and even those that do require a loop to process them all.

ralphm
—
2011-10-29T11:54:05Z —
#17

felgall said:

In HTML you can link to an id ... In JavaScript all browsers support getElementById ...

That's what I meant by my poorly phrased comment:

ralph_m said:

I basically reserve ids for JS and on-page links now.

dresden_phoenix
—
2011-10-29T21:01:42Z —
#18

Felgall is right.

I use this to keep my mind straight about specificity.

(pseudo classes aside)The greater count of tags beats the lower count.ONE CLASS beats any count of tags (w/o classes).The greater count of CLASSES beats the lower count.ONE ID beats any count of classes and tags (w/o IDs).The greater count of ID beats the lower count.You can add lower value items to break ties...(ex: div .menu or even ul.menu beats .menu)IN CASE OF ABSOLUTE TIE, for any of these situations, what ever is last in the stylesheet wins.

If you keep in mind those guile lines and the fact that CSS rules do not determine a PATH to an element per se... everything about specificity becomes transparent.

I eventually got my mind round specificity when I decided that the W3C had used the wrong name for it. I agree with DaveMaxwell that an id attached to a tag should be regarded as more specific than three ids attached to ancestors. So I gave up thinking of rule "specificity" and started thinking about rule weight, which (for me) simplified things no end. Three of something clearly weighs more than one of something, irrespective of position, so that rule should win out.

Slightly Off-Topic:

DaveMaxwell said:

Like I said, it doesn't make sense to me that something applied directly to an element can get overridden by the "generic" base on the parents (guess that's the programmer in me), but I know I need to re-configure my understanding of it, and more importantly, re-configure my co-workers understanding as we're making more and more use of LESS (personally, I'd rather use less LESS and more straight css) and these situations are going to come up more and more.

I'd never heard of LESS until I came across it on the forums, and I decided just now to follow the link and learn more about it. Well, that's another thing that's misnamed. It shouldn't be called LESS CSS, it should be called NO CSS, because that's what you get if you have Javascript disabled. (Apart from the one in-line style used to place an image over the text so it's difficult to read.) This is progress? :rolleyes: I'm afraid I still don't know any more about LESS than that, because I lost interest at that point.

DaveMaxwell
—
2011-10-31T15:31:24Z —
#20

Sorry it's taken so long to get back to this thread - had a power outage and downed trees (onto cars) over the weekend, so I'm just now getting back to this thread....

Paul_O_B said:

I think you may be confusing inheritance with specificity a little as inheritance has nothing to do with specificity really. A child will inherit certain properties from its parent should no more specific styles apply. If for example you set a div to have a font-size of 40px then its children will inherit that 40px font size unless there were more specific rules.

That's a definite possibility, but like I've said before, I didn't understand why a id style that matched directly on an element would be overridden by a cascading style. Yes, I now (mostly :shifty:) understand the count types of rules - doesn't mean I have to agree with them. The logical side of me says the process should be (yes I know it doesn't, but I feel it should)[LIST][*]Apply any styles which match exactly by id with highest precedence[*]Apply any styles which match exactly by class next[*]Apply any styles that cascade from there....[/LIST]

Paul_O_B said:

The C in CCS is not called cascading for nothing.:) Unlike scripting it's an amalgamation of rules that finally style the element and those styles could be a combination of rules from many sources.

Oh, I understand that - it's this particular scenario which seems bass-ackwards to me.....

ralph_m said:

PS Unless I missed it above, CSS does offer !important as an escape clause, though I've never actually resorted to it. E.g.

I don't like to use !important as it can cause other issues - I'd rather just simplify the styling....

TechnoBear said:

I eventually got my mind round specificity when I decided that the W3C had used the wrong name for it. I agree with DaveMaxwell that an id attached to a tag should be regarded as more specific than three ids attached to ancestors. So I gave up thinking of rule "specificity" and started thinking about rule weight, which (for me) simplified things no end. Three of something clearly weighs more than one of something, irrespective of position, so that rule should win out.

Glad I'm not the only person who thinks this way

TechnoBear said:

I'd never heard of LESS until I came across it on the forums, and I decided just now to follow the link and learn more about it. Well, that's another thing that's misnamed. It shouldn't be called LESS CSS, it should be called NO CSS, because that's what you get if you have Javascript disabled. (Apart from the one in-line style used to place an image over the text so it's difficult to read.) This is progress? :rolleyes: I'm afraid I still don't know any more about LESS than that, because I lost interest at that point.

Luckily, we use it more as a developmental tool than truly "LESS", and we build the css files when we move to production. We're not using the full power of it (nor do we need to), and as we're still feeling out what needs to be done, we're following the KISS principle before going live...