Before I get into the meat of this post, I’ll just provide some context. Last week, Harry Roberts posted a fantastic article discussing his view of bad CSS. In that article, as he’s done before, he disourages the use of IDs as selectors.
In response, Jeffrey Zeldman tried to defend the use of ID selectors. I posted a few comments in response to Jeffrey and another commenter, explaining why I felt their views were wrong.
After a few further exchanges, Zeldman then responded with this, which I’ll quote in part here:
ID for single elements and classes for multiple isn’t an “old-school method.” It’s how the elements are defined in HTML. A correct understanding of HTML is not “old-fashioned.” Nor is it “old-fashioned” to use HTML elements as the W3C intends them to be used.
His concluding words in that comment also are relevant:
My post was in part motivated by a desire to push back against the viral uptake of misinformation.
Of course a love of the power of code minus a respect for (or understanding of) the immense true power of HTML has been the web’s besetting sin since the first table layout. It’s been the norm for much of the web’s history for developers to build cool stuff on a lousy, unstable framework, and dismiss the very notion that HTML semantics matter. For a time, in the 2000s, we were able to change that perception, and, thankfully, a lot of folks in our industry still believe in the value of accessible, semantic markup. I worry about the ones who don’t, but you can’t save everybody.
My further responses have evidently been eaten by his spam filter, so I thought I would summarize in this post that the spec does not support his view.
Do Machines Read IDs?
In the semantics section of Dive Into HTML5, Mark Pilgrim explains:
The div element has no defined semantics, and the id attribute has no defined semantics. (User agents are not allowed to infer any meaning from the value of the id attribute.) You could change this to
<div id="shazbot">
and it would have the same semantic value, i.e., nothing.
But what about the W3C? Here’s what the HTML5 spec says about the ID attribute:
An element’s unique identifier can be used for a variety of purposes, most notably as a way to link to specific parts of a document using fragment identifiers, as a way to target an element when scripting, and as a way to style a specific element from CSS.
Identifiers are opaque strings. Particular meanings should not be derived from the value of the id attribute.
The most important part is the last sentence, that meanings should not be derived from the value of the ID attribute, just as Pilgrim explains in his book.
As far as I understand, this is the case whether we’re talking about a screen reader, a search engine spider, or a customary browser. None of these machines get any “semantics” or meaning from an ID attribute.
Are IDs Beneficial to Screen Readers?
Yes, but not in terms of semantics. WebAIM discusses how IDs can improve the accessiblity of tables, and I’m sure most of us are familiar with the concept of matching IDs to <label>
elements using the “for” attribute, thus making forms more accessible.
But those benefits have nothing to do with semantics. They are for the purpose of associating certain elements with other elements on the page.
It should be noted here that I’m not an accessibility expert, so if I’ve left anything out, I’m happy to make corrections or additions.
What Does This Have to Do With CSS?
The problem with all of this is that it’s completely beside the point. Even if IDs somehow did make pages more semantic, this would not change the problems that they cause in CSS when they’re used as styling hooks.
The argument against IDs as selectors does not imply that they should not be used in HTML. The argument is about styling hooks, not page semantics or document structure.
ID selectors are too specific and they mess up the cascade if they’re overused. Yes, you could use ID selectors on only a few unique elements, and you probably wouldn’t have too many problems. But why would you need to do that if you can just use a unique class name instead? And if you absolutely must be able to recognize a “unique” selector in your CSS, you can just use a prefix or something, so it’s clear that it’s not a reusable class. So instead of this:
#header { }
You can do this:
.header-main {}
Or, if you must:
.id-header {}
This keeps your CSS clean and on a level playing field, with few or no specificity issues.
What Does the CSS Spec Say About ID Selectors?
Here’s what the CSS3 spec says in the section on ID selectors:
Document languages may contain attributes that are declared to be of type ID. What makes attributes of type ID special is that no two such attributes can have the same value in a conformant document, regardless of the type of the elements that carry them; whatever the document language, an ID typed attribute can be used to uniquely identify its element.
The focus here is on the uniqueness of the element, not on semantics. This uniqueness is beneficial for fragment identifiers and for JavaScript hooks, but it has no benefit semantically.
And naturally, nowhere in any spec (CSS or HTML) does it say that you are required to use IDs as selectors in order to keep your documents semantic.
Concluding Remarks
I really think Zeldman got too caught up in trying to oppose some of these “new wave” views, without thinking things through properly, or doing the necessary research.
I would definitely not respond in this way if he wasn’t as influential as he is. He has nearly 300,000 Twitter followers and who knows how many blog readers. If even 10% of those readers and followers take away from that post that ID attributes or ID selectors can make your documents more semantic, that would be a great disservice to the community.
I won’t lose sleep if people still use IDs as styling hooks. That’s their choice, and they’re entitled to it. But to suggest that our documents are more in line with W3C standards if we use IDs as selectors, or to suggest that our content will be more accessible or semantic if we use IDs in our HTML is not in line with W3C standards.
Without choosing sides on this, I suggest you should consider the following:
Just because you may want to argue on one specific point does not mean that it’s the only point worth debating.
It’s also worth considering that to gather data about what new elements to add to HTML5 that IDs of millions of documents were parsed! No semantic value huh? Only lead to be a part of the justification of creation of a new set of semantic elements.
There is that.
Well, except that it’s not true. :)
Here’s what Ian Hickson said when asked about how the new semantic elements were added:
Source
Thus, the adding of the new semantic elements came before the so-called “document parsing”. And this is not to mention the fact that this “parsing” still has nothing to do with making your documents more accessible or semantic.
And they used classes for the test, not id’s… ;-)
Excellent post! Can’t describe it in any other fashion ;-)
The main misunderstanding is between using ID’s in HTML and CSS. Everybody is (and should be) using ID’s in their HTML for accessibility and JavaScript hooks, but that doesn’t mean they’re a good choice for CSS.
Harry’s article is great and he has excellent views on these type of things. Sure, everyone is free to do as he pleases, but saying it’s “misinformation” is harmful to the community and (in the long run) to the progress of our jobs.
It’s a simple pro-con issue, where the pros vastly outweigh the cons, so case closed.
Thanks again for the article!
Not that it makes a major deference if you are using HTML5 then ideally you would just reference in the css with the <header> tag.
My main reason for using #idofsomething in css is to avoid defining a class and an id on a tag, clever cascading in CSS will always be the main point.
The problem with using the element type selector (i.e.
header {}
instead of#header
), is that HTML5 allows the use of multiple headers on a single page. And not to mention that this type of overqualifying of selectors that are high up on the DOM tree can be just as bad as using ID selectors.That’s why I still use classes on those elements, and if I need an ID on there for fragments or JavaScript, then I’ll have both a class and an ID, often with the same, or similar value (which some people cringe at).
HTML5 allows the use of multiple headers but it doesn’t require more than one. If you need more than one, you can always add other
<header>
s and classify each one according to its use. You could even set a master ruleset on the<header>
element type selector and write variations into each classified header. This would be fine.Also fine: You could use an element selector or an
id
without classes for a single instance, write CSS for it, and switch to aclass
when you need more than one instance. This is because at any stage in development, before and after deployment, you can return to the markup, stylesheets, and scripts, and edit them. Whenever a new pattern appears — by repeated viewing, by managerial mandate, by dream — you should rework the code to match that pattern. You can, you should, and you will do it again and again, until you move on to another project’s codebase.You could do a lot of things, in point of fact, and not many of them are going to be objectively wrong. The ones that are objectively wrong are potentially one or two spec revisions (and/or one aspirant thought leader’s rhetorical coup) from being objectively right. That could happen tomorrow or two years from now, and it could instantaneously deprecate your argument, if not your practice and reputation in the process.
That’s why I only go in for so much by way of “best practices.” I watched Zeldman work hard to unseat David Siegel, I’m watching Paul Irish and Nicole Sullivan break our love affair with Zeldman, and soon enough we’ll have a new demagogue step up to tell us how to do it right. And when we see that new alpha-(fe)male looming over us, we’ll all have to adapt to the new absolute values again, because the longer we’re working in the field the more likely our employers are to hire “passionate” young men and women to manage us, and those “passionate” managers are more likely than not to be disciples of whatever development idea was hot when they graduated. I’d be careful about designating disservices or misinformation.
Well, I’ll say this:
Machines will never glean semantic value from IDs. That will never change. So I’m not worried about these words becoming obsolete. But I’ll gladly post a correction should Hell freeze over. :)
If machine-readability is where the work begins and ends, sure. That it’s not — that humans and human needs and values figure prominently in the work — is a large part of Zeldman’s argument.
But fair, fair. The line of reasoning you walked him down wasn’t one that he could walk back with any ease. Which is not to say the case you present is true so much as successful. (Which in a way validates his case.) In any event, I hope the feeling’s good.
Is that what I did? Is that what we are?
I think that’s a minority view, if that.
I think the splintering of the community is inevitable. People have different goals and different ideals. I think that’s why WebPlatform.org was launched, to help in these areas and get these types of views more unified.
@Louis, I think your reasoning regarding using classes over IDs for styling is pretty sound, but I disagree with the following:
“In response, Jeffrey Zeldman tried to defend the use of ID selectors. I posted a few comments in response to Jeffrey and another commenter, explaining why their views were wrong.”
You state that they are wrong as if it is a fact. As solid as your logic is, it’s still not a fact. There wouldn’t be two “camps” if it were a fact. I think that is exactly the reason why Zeldman blogged about this topic: stating some practices as the only valid best practice in every scenario as if it is a fact. He objects to that. I tend to agree. I think this is the wrong way of approaching a debate. Because a debate it is.
Furthermore, as @Reinier remarked already, the misunderstanding was between using IDs at all or using them for styling. Only at the end of the thread at Zeldman.com was this cleared up. That means everything before that ending was a discussion on a misaligned topic. It would be fair to more clearly mention that, rather than selectively replaying parts of the conversation this way.
“My further responses have evidently been eaten by his spam filter, so I thought I would summarize in this post why he’s wrong and why, in fact, he is the one that is spreading “misinformation”.”
I once again have a problem with your style of debate here. Accusing somebody of spreading misinformation is pretty harsh. You do build up a good argument as to why you think this is so, but you could have simply said that you disagree with his views. It’s not a random internet commenter you’re talking with. It’s Zeldman, a pioneer in web standards, to which we owe a lot. Like anyone else, he can be wrong, and he does not require special handling, but I think it’s better for the community as a whole to be a little less hostile. Even more so because the actual issue at hand is pretty meaningless compared to other issues.
Ending positively, I salute your role in promoting best practices, and I don’t need convincing on the actual matter at hand, I just hope you take my feedback constructively on how you handled this. Pick your batlles. Sometimes even when you’re 100% convinced that you’re right, the effort and damage involved in actually getting it confirmed is greater than the actual benefit of being right.
Regarding the statement I made “explaining why their views were wrong”, believe it or not, I changed the wording of that about three times, but I went with the stronger wording, because I don’t think it’s my opinion that ID selectors cause problems; it’s a fact. I’m pretty stubborn aren’t I? :)
And regarding the statement that he was spreading “misinformation” — that was his word, not mine (from this comment). I used the word a few times in this post as a response, because I didn’t think it was right for him to put me in that category, as nothing that I said was anti-standards.
Maybe it was a bit harsh, but like I said, that was his word, not mine. I was just trying to defend my own reputation by showing that I was well within the realm of documented web standards (which he accepted).
But, for the record, if my words to Zeldman sounded harsh, then I apologize. Maybe ‘responding in kind’ wasn’t the best route, but I think it resolved itself in the end, as I don’t think he’s upset at me for any wording I used. Again, I only did this because of the huge influence he has, and the potential effects it might have on developers’ understanding of “semantics”.
I’m also stubborn, so that makes two. I accept the fact in your first paragraph, but it’s a smaller piece of the larger discussion, which is not 100% factual, and also started from different grounds. I won’t make the mistake of explaining the difference, because that’s not my point. My point is that even near-facts or 100% facts will not be swallowed by every member of a huge community without some resistance. The question is, is all that effort, possibly negative energy and fights over reputation worth it for the outcome? I think not in this case, but only you can be the judge of that.
Even with facts, logic and solid reasoning behind you, you cannot ram them down somebody else’s throat. For the simple reason that human beings arent rational beings.
One more thing you mentioned:
Yes, you are correct to some degree, but Zeldman’s idea that IDs are semantic was stated right from the start in the original post. He said:
I don’t want to beat a dead horse here, but twice he mentions that IDs are semantic, which is incorrect. He repeated this concept in the comments and then implied that people like me were spreading disinformation by telling people to avoid IDs. That’s why I posted this.
And believe me, no one was more nervous about responding to this issue than I was. But I knew a lot needed to be cleared up and nobody else seemed to be stepping up to clarify things.
But all this having been said, I’m going to change the wording of my post, because you’re probably right that it sounds a bit harsh. Thanks for the constructive advice.
Ok, I’ll make the one mistake to actually go into the topic: I tend to agree with Zeldman’s statement here:
“There is nothing wrong with id when it is used appropriately (semantically, structurally, sparingly)”
I think this is said in the context of using IDs at all, not specifically for styling. In that context, I agree with this statement, both in theory and in practice. A practical reason is hooks with Javascript. IDs do have *some* semantic value, in that it tells developers that this element will only appear once. There’s more to semantic value than browsers or search engines. Having said that, I acknowledge that the semantic value is low, maybe even neglectible. And that’s exactly what he’s saying “There is nothing wrong”. There is no strong benefit but no strong downside either, when viewed in the context of using IDs at all, rather than specifically for styling.
I’m not hoping to open the discussion again, I just want to point out that the discussion has subtleties in it that make it a discussion, and not a matter of fact forcing. And a healthy debate in my mind allows multiple views, including views that you think are 100% wrong.
Louis,
With you’re putting the cart before the horse. Why would you need to give an element a unique class name if you can use its ID instead? (Classes are per definitionem not meant to be unique. IDs are.)
If you’re afraid that
, simply use the attribute selector.[id="foo"]
has exactly the same specifity as[class="bar"]
a/k/a.bar
. Problem solved. (If there was one.)But do ID selectors really your friend, not your enemy.
? I don’t think so. I’m afraid of no ID selector. Make specifityClass names beginning with ‘id’ are – to quote Terry Pratchett – “a sure sign of an insane mind.” ;-) Well, at least they are a sure sign that you really would want to use an ID, not a class.
Who did
? The W3C issues rather technical specifications (whan can be done) than best practices (what should be done) in web development.The main reason I prefer classes, even unique ones is for reusability. The truth is, there is rarely an element on a web page that does not have styles that can be abstracted. That’s why it’s good to use classes even on unique elements, because it will get developers into the mindset of reusing and abstracting styles, rather than (for example) having 30 different font declarations, many of which have the same font declared. And that’s for a small site.
And to answer your last point, it was Zeldman’s post and his subsequent comments where he specifically stated that avoiding IDs meant we were promoting ideas that were not in line with the spec, and what IDs were made for. I was responding to that point. I was not suggesting that many developers are saying this, it was just his post (which he’s now recanted to some degree, particularly on the semantics issue).
I guess i get the point by now for using ID selectors in CSS. If your document has the need for an ID, why waste another class for styling it? You just have one #header, so you can style this according to your needs. Nonetheless, I think in terms of maintainability classes are alot more flexible when it comes to restructuring your website. E.g. if you switch from old-school HTML to the new semantic HTML5 markup: Going from
<div id="header" class="header-main">
to<header class="header-main">
will leave your CSS reusable. Just styling tags is not an option here, since header can be used more often than onceThe only legitimate use for ID’s in CSS (in my opinion) would be if you style a unique widget (e.g. for a CMS) that can be installed separately and you want to make sure it doesn’t clash with other styles (that you don’t know about).
Even then you could probably resort to classes, although you would still need to try and make it unique as it could be overwritten by existing styles.
@Louis Lazaris
Hickson’s research is flawed and brings up a rather disturbing trend I have seen for about 10 years in the business called, “buy the premise buy the bit” it is how comedians write jokes. But I would not what to infer that html 5 is a joke. (would I?) What was the research method and practice? Taking someones word for it is not science.
He said he and his little buddies only researched the top 10 classes which is a bias in the first place and shows how he is leaning. You can not research an environment without considering all samples. That sample had to include ID’s to be valid. Otherwise it was and is garbage.
Ever been to a school? Was it a big school or a small school? Was it made of wood? Was it made of brick? Was it an elementary school or a high school? An id is a unique adjective to describe and further define an element. You can have an elementary class or a high school class that generally describes what each is. You can not tell what type of school it is. Atomic objects like new elements or whatever have to be used sparingly and with caution.
Using classes everywhere is a hack. Like only having one tool in the tool box. I don’t pound screws into wood I use a screw driver.
Content mechanisms and frameworks ARE NOT good places to research what is best practice. Daisy chaining class after class is scope creep, bloated AND creates convention rather than a modular environment. It is not maintainable without throwing the baby out with the bath water.
Doesn’t anyone build their own tools anymore so they can see what goes on under the hood? Web development is a practice and a science. not undocumented, empirical, circumstance.
If you used a screw driver that always gashed open your thumb because it was mechanically unsound, would you continue to use it?
There’s nothing wrong with discarding a tool that causes you problems, as long as you don’t need that tool. It’s not like IDs are the “”:hover” pseudo-class where there is no other option. They are replaceable and it is absolutely not a hack to only use classes. That’s like saying it’s a hack to avoid global variables in JavaScript.
“That’s like saying it’s a hack to avoid global variables in JavaScript.”
Wow! Silly comparison! What do IDs in an html element, or IDs used as a selector in a stylesheet have in common with JavaScript’s global variables? You’re comparing a Programming language with a query language. Apples -VS- A Forest of Oranges!
JS global variables have been proven over many, many years to create problems and generally accepted as a Bad Practice in the JavaScript community (not to say that other practices aren’t a bad practice either). There is no indication in the general Web Development community that #IDs are a bad practice (unless the community is made up of you and your friends).
An ID in a stylesheet is a perfectly usable tool that doesn’t cause any problems (it could actually solve problems if you know how to use it properly) for many Devs around the planet, and as such any suggestion that “var global === #id” is nonsense!
However, if you really want to suggest that “var global === #id”, then using only classes in you CSS can be compared to only using a JS style like the following:
Nice response… I totally agree!
Actually, there is every indication in the community that IDs cause problems (as selectors). It’s not just my friends (and that’s besides the fact that I don’t hang out with web developers in my spare time).
The comparison I’m making is not at all inappropriate. Both global variables and ID selectors have been shown to be problematic as optional features of their respective languages. Neither feature is required.
The reason I made that comparison has nothing to do with the nature of the languages, and everything to do with the fact that they are optional features and that many experienced developers say that they cause problems and can be completely replaced by other more maintainable methods.
From the article: “But why would you need to do that if you can just use a unique class name instead?”
Because class names aren’t unique. It’s that simple. I don’t know why you are attempting to retard the semantics. ID’s are fine for your header, sidebar and footer, just use classes on the (repeatable) content. It’s not hard. Anyone getting lost between using # or . in CSS probably shouldn’t be in the business of programming.
It’s more speedy and have a better priority! Why not if it’s a HTML 5 which have a best tag names for better uniqueness ? :)
I haven’t read all of this by any means so this may have been discussed:
There is of course a double meaning in the word “semantic”. From one perspective, in the way the W3C spec seems to use it, it means “Machine parse-able”, but of course the basic meaning is something like “relating to meaning in language or logic” (dictionary.com), which is ridiculously general, but more specifically it can refer to parse-ability by human beings.
In the case of “semantic class names” in CSS the intention is that the CSS classes mean something to front-end developers regardless of how the element is styled. The fact that an ID is understood by most front-end developers to be unique within a document, therefore an ID selector (rather than a class selector) will have semantic value *to them* – it’s a way of saying “this is intended to be a unique item on the page”.
However, I personally think that the disadvantages of using ID selectors far outweigh this benefit, and if it’s really important to convey uniqueness you could always add “unique” into the class name (it’s not like the uniqueness of ID elements is enforced in any way anyway, unless you run your mark-up through a validator).
However, I do still think IDs can add semantic value to your mark-up (once again probably human-semantic rather than machine-semantic), with the added bonus that those IDs are then targetable in the URL (/mypage#the-actual-story) and it’s probably good practice to use IDs in your mark-up where appropriate – just never target these IDs with CSS.
So when I use classes instead of ID’s, will it speed up my website? because if that’s the case then I will start using classes instead of ID’s
No, there will not be any difference in speed. The point of using classes has nothing to do with performance. It’s for maintainability and avoiding specificity problems.
Selection by Id is faster in javascript then class selection, one of the reasons is that javascript stops selecting after finding the id.
Btw this whole discussion feels a bit like one of those ‘front-end developers with to much time to overthink discussions’ :).
Please get a life, the id vs class debate is more tedious than watching paint dry.
Mr. Louis Lazaris, I can conclude that you very much like debates and you don’t concede when you “think” you are right. That’s good if you are “right”. But please note that there is a constructive way of lecturing. Yours is a very, very destructive one.
I can’t imagine you could say something like this…
You need not say such things. What are you implying, that Zeldman is old school and needs to be disposed?
Mr. Louis Lazaris, imagine yourself being lectured on destructively, pointing out every mistake that you’ve made. Would that make your day? I really hope that you change the way you write your articles because the audience that you are captivating are also becoming destructive in the way they comment.
Mers, there is nothing “destructive” about a harmless online debate.
And no, I’m not implying that Zeldman should be “disposed”, only that he should ensure that his statements are factual.
If you read the thread of the original article that I responded to, Zeldman acknowledged that I was correct. I was not stating an opinion in this article, I was merely pointing out that his statements were false, which they were, and which he conceded.
Here’s how I saw everything while I read some of your articles.
I was actually looking for solutions to problems regarding HTML5, and I found “this” site. Everything was interesting at first, until … you got to rant so much about how the other person is wrong, and how you are so very right. In fact, your self-righteous ranting made me forget what I was looking for and made me start thinking how annoying the way you deliver your message.
Don’t get me wrong, you’re very, very good. But ramming your greatness right into other peoples’ faces doesn’t help you deliver the message through. A little subtlety and kindness in words could help.
I’m not a writer so I really don’t have the right to judge you about the way you write. But I’m a reader, and I can tell how a certain form of writing affects me and the way I see the person who wrote it.
You may be skilled and knowledgeable Mr. Louis Lazaris but you won’t impress people with your negative attitude. I only ask that you be impressive in both your skill and character. That way, this website of yours impressivewebs.com will certainly be impressive in more ways than one.
Everything we write on the web is read by thousands, even millions of people. We all have our own opinions and beliefs. We can deliver any way we want but IMHO, usually it’s how we deliver our message that makes a lasting impression.
Mers,
I appreciate what you’re saying, and I’m not trying to sound defensive, but I have no choice here. You’re attacking me and being just as negative as you claim I’ve been.
How do you suppose a person can point out another person’s errors without sounding “negative”? There is no way to do such a thing without some negativity.
Yes, I can choose not to point out anyone’s errors and just go about my business. But besides the fact that that wouldn’t be very fun, it’s also much less constructive. You have to understand something here: Jeffrey Zeldman has 300,00+ Twitter followers and probably more than 50,000 blog readers. If he’s going to tell that many people that IDs make documents more semantic, then I’m going to point out why he’s wrong in that.
In my post here, I never once said Zeldman was stupid, or anything even remotely close to that. I never attacked him personally. I never implied that he wasn’t doing things with the best intentions or that I questioned his motives. He simply made a mistake and I felt that it warranted a full blog post with all the technical details.
I have written many articles that have been debated by people online, both in constructive and non-constructive ways. I did not view those debates as “negative” or “destructive”. I’m sorry, but you’re being way over-dramatic here over nothing.
I don’t even understand what it is exactly that you found “negative” and “destructive” in my explanation in the post. Can you please provide a quote from the article that you feel could have been worded differently?
How would you approach a situation where someone prominent in the industry makes a serious technical error, passing it off as fact? I commented on his original blog post and it got eaten by his spam filter, so I posted it on my site with a more extensive explanation along with links.
Again, I ask, what specifically in this article do you find to have “negative” or “destructive” wording?