homepage Welcome to WebmasterWorld Guest from 54.226.191.80
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Home / Forums Index / Code, Content, and Presentation / CSS
Forum Library, Charter, Moderators: not2easy

CSS Forum

    
id or class, I didn't think it mattered that much
calculating specificity
jackherbert




msg:4281721
 1:36 am on Mar 15, 2011 (gmt 0)

I know what you're thinking "Don't tell me this doofus is gonna ask us what's the difference between a class and an id"
I'm not, i'm pretty sure i know that: It happens once, use an id; It happens many times, use a class. Basic stuff.

Now, I thought that when it comes to the styling itself, whether you're using class or id, it should have the same effect on your element, but it looks like I thought wrong.


Here's my test case:

I have a <ul>,in there I stuff two <li> and in the second <li> I want to put two images next to each other.


<li>
<img blablabla>
</li>

<li>
<img id="foo" blabla>
<img id="foo" blabla>
</li>


I shouldn't have two "foo" ids, but I was just testing and thought I'd change them too classes afterwards.

the css goes like:

li img {
display:block;
}
/* ^ that's just for the first li img */

#foo {
width:50%;
display:inline;
}


Okay, so far so good, the first <li> has one picture and the second has two smaller ones, showing side by side.

Great, now I change the ids to classes and SHABOOM!
The pictures in the second <li> are back to block display instead of inline. All I done was changing the id to class (in both the html and the css files).

Am I missing something?

 

Fotiman




msg:4281872
 12:53 pm on Mar 15, 2011 (gmt 0)

Did you change the selector in your CSS to a class as well? In other words:

#foo {
width:50%;
display:inline;
}

would become:

.foo {
width:50%;
display:inline;
}

calder12




msg:4282006
 5:03 pm on Mar 15, 2011 (gmt 0)

Easiest way to find these things out is use Google Chrome as your browser, right click the offending element and choose Inspect Element. On the right side it will give you the CSS breakdown and show you where it's getting it's display elements from.

My guess is you have a cascade issue somewhere since ID's are the most important and Classes second.

Check out this link for an explanation: [blooberry.com...]

SuzyUK




msg:4282215
 11:31 pm on Mar 15, 2011 (gmt 0)

It matters a lot! - you're talking specificity, an ID will always override a class no matter where in the Cascade it occurs (search Sith Wars Specificity for a light hearted look at this! it's slightly outdated but essentially correct ;))

even at the "class" level if those list items have another class which is targeted more specifically (uses more elements in its selector) than your foo class then it will win

seriously you can use the class "myclass" all over the place in your page you can target it as one thing
.myclass{} or you can target it by element - BUT as soon as you add another level to the selector you make it more specific

div ul li.myclass {}
table tr>td.myclass {}


is more specific than

li.myclass {} or ul .myclass {} or td.myclass {}

but they use the same class to target.. or classify

it won't matter how many rules you write for
.myclass{} your ul.myclass{} or li.myclass{} will override them in the first instance, and your ul li.myclass {} or tr>td .myclass{} will override the second version too

I know what I'm trying to say it's just not happening - the Cascade will only work if the selectors are of the same specificity, specificity can always be used to override the Cascade, it might seem a bit back to front, but it does make perfect sense really it does.. specificity has always been more important than the Cascade!

if you don't know what "specificity" is yet.. try looking on W3C for specificity calculations or try searching for an online "css specificity calculator"

Firebug will help find out what rules override another but if you want to know why a rule is "overridden" then a calculator might help

swa66




msg:4282392
 12:43 pm on Mar 16, 2011 (gmt 0)

Specificity is at the core of understanding how CSS was engineered and intended to work.

It's not all that hard to understand: it sets the priority of individual settings based on how specific the selector was. If the CSS engine can't find a solution based on specificity, only then will it look at source code order to give priority to the last setting.

You have to think of specificity as a "number" with 4 "digits".
Now the digit paradigm works till it goes over "9", hence most write it as a dotted quad.

The lowest prority digit is the element, next the class, then the id, and finally the inline style.

So the specificity of
li {...} is 0.0.0.1
li img {...} is 0.0.0.2
.myclass {...} is 0.0.1.0
li.myclass {...} is 0.0.1.1
li.myclass img {...} is 0.0.1.2
.menu li.myclass img {...} is 0.0.2.2
#myid {...} is 0.1.0.0
#myid li.myclass img {...} is 0.1.1.2

etc.

Now how is that used ?

CSS:
.myclass {color: white ; font-weight: bold}
li {color: red ; background-color: green ; font-size: 14pt}

HTML:
<li class="myclass">test</li>

For font-zize, font-weight and background color: there is no need to look at the specificity as they do not conflict and *ALL* are applied.
for color, there is a need to look at the specificity: the text will be white.

There is one exception: the shorthand notations reset those setting they did not set themselves.

calder12




msg:4282402
 1:22 pm on Mar 16, 2011 (gmt 0)

Specificity that is the word I was looking for yesterday and couldn't remember lol >.< I am self trained but I watched a very good Lynda.com video on that part of CSS and it was very informative.

SuzyUK




msg:4282754
 12:23 am on Mar 17, 2011 (gmt 0)

thanks for the samples, can hopefully explain more now,

so specificty is the reason why a single ID will override any amount elements and classes which is why they, ID's are so important

yes IE used to have an issue with chaining id's and classes so that may have had a bearing as to why this was not used properly as IE6 is still floating about I believe ;)

but the essence is .. to use 2 of swa's examples with a slight change

.menu li.myclass img {...} is 0,0,2,2 - (2 classes, 2 elements)
#myid img {...} is 0,1,0,1 - (1 ID, 0 classes, 1 element)


if that pertains to
<ul id="myid" class="menu myclass red green bold whatever">
<li class="myclass"><img src="#" /></li>
</ul>


the first CSS rule
.menu li.myclass img {}
has 2 elements (li and img) and 2 classes (menu and myclass) in it's selector so its pretty specific - now if it's setting the background-color of the image to pink then it's likely to be taken.. the selector reads from right to left as true, it matches , it has an ancestor list element with a class of "myclass" which hsubsequently has an ancestor with the class of "menu" so the background color will be applied

but the second rule
#myid img {} no matter where in the cascade it appears it will override the first, that single ID is enough to override 10 million classes and elements

even if you chain all the classes together for
.menu li.myclass img {...} so that selector becomes:
.menu.myclass.red.green.bold.whatever li.myclass img{}

the specificity of that selector then becomes: 0,0,7,2 (7 classes and still 2 elements) - hehe, the image is pretty sure to have a pink background now ;)

but let's bring back the ID..
#myid img {} it's specificity is 0,1,0,1 (1 ID, 0 classes and 1 element)

in simple terms 101 beats 72 (lack of commas is deliberate) BUT that's not the way to see it even though it works most times, rarely are there more than 9 classes chained ;), specificity is not base 10, it's not even base 16 - it's an unknown base if you like. The commas separate the columns and the columns order of importance is the same as CSS they're read right to left, he further left you get the more important!

You could , for example, have 300 classes on your element and chain them all together like the 0,0,7,2 example - if you did that the selector would the have a specificity of 0,0,300,2.. but still the 0,1,0,1 would beat it, thanks to the ID, the ID puts a one in the "hundreds" (3rd from right) column which beats the 0 - the 300 and the 0 in the "tens" (2nd from right) column are negated as soon as there are any ID's in the race..

btw the fourth from right column is for an inline style
<ul id="myid" class="menu myclass red green bold whatever">
<li class="myclass"><img src="#"
style="background: red"> /></li>
</ul>
it will trump even an ID, as it will put a 1 the fourth from right column for that particular img the background will be red, and the specificty is 1,0,0,0 .. no selector beats that, no matter how many classes or ID's chained ;) - that's why inline styles should be avoided unless they're being added or changed by JS in which case the JS can also take care of the styling!
swa66




msg:4282888
 10:46 am on Mar 17, 2011 (gmt 0)

Might be useful to add that the wildcard selector has zero (0.0.0.0) specificity.

So any setting (no matter the order) that conflicts with a setting that's used in a "normal" selector will win out.

So:
* { margin:0; padding:0; border:0;}
Will set margins, pading and border to zero, except there where the CSS states it wants any of them (common reset rule often used to get rid of browser specific default settings)

Now wait a second am I statign here that somethign with zero specificuty still can overrule build-in defaults from a browser ? So there must be more priorities involved somewhere ? Sure there is: it's called the cascading order.
This specificity is only for CSS from the same origin. The cascade defines the priority base don the origin of the CSS. It's what allow user stylesheets to override our work [e.g. for somebody needing a bigger font, or better contrasting colors])

More info here:
[w3.org...]

Now that shows the !important way of marking rules to be more important. I'd be extremely cautious to use that: specificity is the tool to use for us authors and we can do what we need to be done without that !important stuff.

!important is of great importance for user stylesheets as it allows them to override our settings based on their needs. [And no we don't get to override those anymore]

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / CSS
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved