tags:

views:

1819

answers:

10

I've been dipping into SitePoint book concerning CSS.

The thing that struck me about the examples was the use of ID as a CSS selector.

Some bits of CSS design I've done, I've always found it easier and more versatile to use Class as the selector.

Maybe its a .Net thing as we don't always have control of the ID of an element...

Is the best practice here to use CLASS or ID as the selector?

A: 

I prefer to use Class as the selector, so I can use it with more than one element at the same page. Using the id as the selector, does not allow this, since the id must be unique.

Alexandre
+14  A: 

I guess they always use the id in examples because it's less ambiguous. You know that they're talking specifically about that one element and its styles.

In general, the rule of thumb is that you should ask yourself: "is there more than one element which requires the same style, now or at any time in the future?", and the answer is even "maybe", then make it a class.

nickf
That sums my opinion up quite well! Use Class, and only use ID as a selector when needed.I'll rummage through the book to see if there was any further elaboration on this....if not I may even email the authors
Adrian
Agreed. It may help to choose ID names that imply uniqueness, like "mainsection" or "navbar."
Nathan Long
+2  A: 

ID selectors have a high specificity, which is often what you need in CSS. The tighter you can get the CSS to apply to exactly what it needs to the less work the CSS renderer has to do in establishing rules.

Design to task, and do so in an OO manner - use classes where the objects are classlike, IDs where you mean to target instances, and treat tag refs as something like interfaces (and beware when you do so!). That's the best practice I can think of.

edit: and yeah MS really shafted CSS with ASP.NET thanks guys!

annakata
Almost upvoted you, until I got to your edit. I have no isues with ASP.NET and my ability to style it correctly.
Tim Meers
@Tim Meers - so you have no problem with having crippled ID selectors, MS's interpretation of browser-upscaling, it's semantic-breaking controls (the so-called CSS friendly adapters were released for a reason) and it's continued insistence on promoting inline styling? If that's fine with you then king's to you, but personally webforms have been dead to me since MVC was released.
annakata
+2  A: 

The practice depends on the 'resolution' of what you're trying to select.

I use classes when I want to change a whole swag of elements. IDs give me a much more fine-grained control which is sometimes necessary.

paxdiablo
+1  A: 

You should use an "id" when you're always talking about a single (and will always be single) seciton of your site.

Basically, it comes down to semantics.

div.header

That's tells me that you allow multiple "headers" in your site. Perhaps these are sub headers.

div#header

That tells me that you're talking about the single "header section" of your site layout.

EDIT: Here's a semi-old article about a Pure CSS design... if you just scan the CSS examples, you'll see why I use ID's in there: How To: Pure CSS Design

Timothy Khouri
+8  A: 

Don't forget that class and ID are not mutually exclusive. There is nothing to stop you from having both! This is sometimes very useful as it allows an item to inherit common styling along with other elements of the same class as well as giving you precise control of that specific item. Another handy technique is to apply multiple classes to the same object (yes, class="someClass someOtherClass" is perfectly valid) For example:

<style>
div.box {
float: left;
border: 1px solid blue;
padding: 1em;
}

div.wide {
width: 40em; 
}

div.narrow {
width: 10em; 
}

div#oddOneOut {
float: right;
}
</style>

<div class="box wide">a wide box</div>
<div class="box narrow">a narrow box</div>
<div class="box wide" id="oddOneOut">an odd box</div>

In theory it is also possible to get CSS to only apply to items that belong to several classes, e.g. div.box.narrow {something: somevalue;} but unfortunately this is not supported in all browsers.

Ola Tuvesson
I know about multiple Classes - sometimes I feel I'm the only one that does...Now I know I'm wrong.
Adrian
Yes, it seems not many have picked up on that. Shame because it is a very good way to reduce clutter and redundancy in stylesheets!
Ola Tuvesson
It's also a nice way to dig yourself a nice and deep hole, unless you're careful. ;) As a rule of thumb; classes (or ids for that matter) should never have names descriptive of the look, but rather of function.
Williham Totland
Got an example of where this would lead to "a nice and deep hole"?
Ola Tuvesson
+5  A: 

Don't forget that you can link to an element that has an ID. This can be very important for accessibility, among the other benefits. This is a good reason why for layout elements like header, navigation, main content, footer, search form and so on, you should always use an ID instead of a Class (or together with a Class).

alexmeia
+1  A: 

IDs are for uniquely identifying elements, Classes are for identifying an element as being part of a class of elements.

In practical terms, id attributes should only be used one per document, class attributes can be used on more than one element on a document.

Check the W3C spec and also the CSS-Discuss page on this issue.

Sam Murray-Sutton
+2  A: 

Another useful resource is the W3C spec on Cascading Order: id selectors are given ten times the weight of class selectors. This is especially important if you plan to override styles depending on different scenarios or state changes. The more specific the initial selector, the more work you have to do to override it in additional declarations.

Zak Linder
A: 

Use only classes, almost never use IDs if you don't have to worry about speed or compatibility.

Using IDs is bad just like using global variables in Visual Basic code. The reason is that IDs have to be unique which introduces unnecessary and bad dependency between different independent parts of your code. Using something like .page1 .tab1>.field1 is better because you don't have to worry about uniqueness of field1 inside tab1 or uniqueness of tab1 inside page1. With IDs you have to keep registry of your IDs to keep control and avoid collisions.

Use IDs only if you have to, for example href='#name' or if some library requires you to.

alpav
And if you need a name applied to a unique element, but only use class, what's the diff? Except the class won't be flagged as an error and you may wind up chasing down a bug if you use the same class elsewhere.
Rob
you have to use IDs in some circumstances. If you use classes ALL the time you create a css file with lots and lots of classes that only have one application...which is very inefficient and a maintenance nightmare!
Adrian
@Adrian: how using #name makes it less nightmare than using .name ?@Rob: right, there is no diff, but the benefit is when you dynamically include one page into another that happens to have same id name or if you combine page components together. How can you write reusable component using IDs unless you duplicate component name inside every ID ? And if you duplicate, what is the point of DOM tree if you are organizing your own tree inside IDs ?
alpav
@Adrian: using lots and lots of local variables does not make it nightmare in programming, how so in CSS ?Making new class names is actually easier than ID names because with IDs you have to worry about global scope and with class names you need to worry only about uniqueness in local scope, same benefit as with local variables.
alpav
IDs have a higher specificity than class. Sometimes you want a style to trump other class styles of parent elements. Most of those times, that's when the element is unique to the page, and thus an element ID is very useful.
ghoppe
Also when using a javascript library like jQuery, it uses the browser’s native method, getElementByID(), to retrieve an object, resulting in faster script execution than when using a class selector.
ghoppe
Lastly, your global variable analogy is flawed. Uniqueness is a feature. An ID is unique to a document and refers to a specific element. Are you saying pointers are bad too?
ghoppe
@ghoppe: I agree about performance, but from code organization point of view IDs are as bad as global variables. Difference in speed is less in modern browsers. Using jQuery for addressing is a hack that will be eliminated in the future with native browser implementations.Using IDs to raise priorities is also bad hack, it's better and there is more freedom if you use additional root elements, for example priority of body div div span.class1{} is higher than body div span.class1{} is higher than body span.class1{} is higher than span.class1{}. !important is useful too.
alpav
@ghoppe on pointers: yes, pointers are bad if you hardcode absolute memory address in your code. If you use relative value then they are ok. Any HTML ID represents absolute memory address if we consider DOM tree as memory and compare it to using class relative to higher level DOM elements.
alpav
I truly am missing your point. If I have a dog named Fido and I want to give it a specific command, I do not find it more convenient from a "code organization point of view" to use .myhouse .contents .dog { position: sit } rather than #fido { position: sit }. Using more root elements simply means more difficulties when the page structure changes. What if I insert another div? Now I have to change my css to account for that rather than knowing #fido will be sitting correctly.
ghoppe
As for your comments on the DOM tree and absolute memory, sometimes (often?) your presentation of a unique element does not care about the hierarchy of the DOM. An HTML ID is not equivalent to an absolute memory address as it does not "break" when the DOM (memory space) changes.
ghoppe
If you have 2 levels of DIV under body designated to prioritization purposes only then you don't have to ever place anything between them and body. So them and body become container and all content would always be below body>div>div.
alpav
@Alpav I'm going to stick with Nickf answer I marked as correct, and also refer you to Ola answer below that too. I really cannot make any sense of your last comment, except that you may be talking about TYPE selectors not ID or CLASS selectors...
Adrian
This discussion continued here: http://stackoverflow.com/questions/2420809/disregarding-speed-and-compatibility-why-not-use-only-classes-and-never-use-ids
alpav
Late to the party, but using ghoppe's analogy `.myhouse .contents .dog` will cause the parser to traverse from every dog it finds back to the DOM root to make sure it's in the house contents and then make sure the contents are in my house (the point about adding divs is moot because these are descendant selectors not child selectors). Is this a performance hit? It depends how many dog owners live in your neighborhood. But of course, we are disregarding speed and efficiency here.
Duncan
On the point about creating dependencies by using ID, you might as well claim that you shouldn't use primary keys because they create a dependency between your code and the database. Finally, IDs certainly do have their place because without them, I would have to address this reply to the guy who made the statement about using classes exclusively rather than the more convenient label of alpav.
Duncan
@Duncan: interesting point about primary keys. I suggest that if data is derived from code or data never changes then hardcoding of primary keys is appropriate, otherwise not.Also I wonder if you prefer to use select * from users where id=nnn or select * from <all tables in database> where id=guid ? I claim that first is better than second just like .users>._nnn is better than ._guidAbout "point about adding divs is moot": div div{attr:val} has higher priority than div{attr:val}, so we can control priorities, why is it moot ?
alpav
@Duncan: About alpav, it is hard to create unique name in global namespace. alpav just happened to be short and unique enough at the same time, but it's rare. Most other names are much less convenient to address and invention of many unique names inevitably leads to duplication of paths inside names. You will have to put paths into queries anyway, but when using IDs you are making it worse by duplicating path inside names instead of using existing tree structure.
alpav