41

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?

Patrick Desjardins
  • 136,852
  • 88
  • 292
  • 341
Mesh
  • 6,262
  • 5
  • 34
  • 53

11 Answers11

51

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
  • 537,072
  • 198
  • 649
  • 721
  • 1
    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 – Mesh Nov 18 '08 at 14:00
  • 2
    Agreed. It may help to choose ID names that imply uniqueness, like "mainsection" or "navbar." – Nathan Long Nov 18 '08 at 16:03
  • I think this answer has it about right. I would express this as "use an ID if and only if it would be nonsensical to select more than one element for whatever you're doing with the selected element". For styling, that is very rare in my experience; you'll almost always be better off with a class. Following this rule, IDs are much more commonly appropriate for javascript, where an operation you'd apply can't be reasonably applied to multiple elements - if there's more than one, there's a problem, so a browser highlighting in the console that you've duplicated an ID would be handy. – Richard Abey-Nesbit Aug 10 '21 at 04:47
21

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. Update 2011: Multiple class selectors now have near universal browser support so go ahead and use them!

Aliaksandr Sushkevich
  • 11,550
  • 7
  • 37
  • 44
Ola Tuvesson
  • 5,062
  • 2
  • 28
  • 37
  • 1
    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 Nov 18 '08 at 15:50
  • 2
    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 Mar 09 '10 at 22:40
  • 2
    Got an example of where this would lead to "a nice and deep hole"? – Ola Tuvesson Mar 28 '10 at 14:35
  • 2
    Just to warm up an old thread: The `div` selector in `div#oddOneOut` is unnecessary. Since the _id_ attribute is unique across the whole page, the `#oddOneOut` selector will be precise enough to match that element. – matewka Mar 17 '14 at 20:15
  • Correct, HTML element name in this case only included for consistency and clarity (I do this sometimes in production CSS as well). – Ola Tuvesson Aug 03 '14 at 00:15
18

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
  • 5,241
  • 4
  • 24
  • 24
  • 1
    This is a good point, but I'd go so far as saying it's normally bad practice to use an ID for both linking and styling. Linking will always relate to the structure of the page, and maintainability is improved by having logical separation between structure and style. If an element needs to be linked to as well as styled (in a way that requires an ID or class), I'd strongly recommend using the ID for the link and a class for the styling. Except maybe if the styling you want to do with it only makes sense so long as there's only one element styled like this on the page (rare), then use the ID. – Richard Abey-Nesbit Aug 10 '21 at 04:52
7

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
  • 1,016
  • 1
  • 9
  • 13
  • 4
    No, not ten times, infinite times! Read the spec again: “Concatenating the three numbers (in a number system with a large base) gives the specificity.” In this sentence, a “large base” is only large enough when one single id overrides any number of class. – Edgar Bonet Jun 18 '13 at 10:25
4

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
  • 854,327
  • 234
  • 1,573
  • 1,953
2

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
  • 74,572
  • 17
  • 113
  • 180
  • 1
    @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 Aug 12 '10 at 08:40
  • Web forms have been much improved since version 4. It no-longer malforms html code (including spacing) and you can now use static ID's and turn off viewstate, session state and you can have routing like MVC. You can harness some of the great features of MVC or mix and match :) – George Filippakos Jan 29 '13 at 08:05
2

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
  • 31,315
  • 21
  • 88
  • 128
1

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
  • 1,016
  • 3
  • 13
  • 23
1

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
  • 1,439
  • 1
  • 13
  • 22
0

Please refer to:

Don’t use ID selectors in CSS: http://screwlewse.com/2010/07/dont-use-id-selectors-in-css/

Don’t use IDs in CSS selectors?: http://oli.jp/2011/ids/

Joy
  • 9,430
  • 11
  • 44
  • 95
-1

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
  • 2,972
  • 3
  • 37
  • 47
  • 2
    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 Mar 09 '10 at 22:42
  • 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! – Mesh Mar 10 '10 at 10:47
  • 4
    @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 Mar 10 '10 at 18:38
  • @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 Mar 10 '10 at 18:56
  • 2
    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 Mar 10 '10 at 19:24
  • 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 Mar 10 '10 at 19:26
  • 2
    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 Mar 10 '10 at 19:37
  • @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 Mar 10 '10 at 19:45
  • @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 Mar 10 '10 at 19:53
  • 3
    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 Mar 10 '10 at 19:56
  • 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 Mar 10 '10 at 20:01
  • 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 Mar 10 '10 at 21:40
  • @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... – Mesh Mar 11 '10 at 10:33
  • This discussion continued here: http://stackoverflow.com/questions/2420809/disregarding-speed-and-compatibility-why-not-use-only-classes-and-never-use-ids – alpav Mar 11 '10 at 17:14
  • 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 Jun 01 '10 at 01:45
  • 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 Jun 01 '10 at 01:48
  • @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 where id=guid ? I claim that first is better than second just like .users>._nnn is better than ._guid About "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 Jun 10 '10 at 17:25
  • @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 Jun 10 '10 at 17:26