I recently installed a csslint package for my Atom text editor. I keep getting warnings saying “Don’t use IDs in selectors.” I found this weird since I’ve always been using IDs in selectors in CSS, and I haven’t really run into any coding or syntactic problems using them.
On StackOverflow, I found posts, like this one, stating that I shouldn’t use IDs because they have priority over classes. However, I found another post that states I should use IDs because they have priority over classes. I understand both of these posts, but I still don’t know if I should continue to use them or not.
Lets say I have this code as an example:
HTML
<div id="opening-subject-container">
<div class="subject"></div>
<div class="subject"></div>
<div class="subject"></div>
</div>
<div id="body-subject-container">
<div class="subject"></div>
<div class="subject"></div>
<div class="subject"></div>
</div>
CSS
.subject {
width: 100%;
height: 20px;
}
#opening-subject-container .subject {
background-color: red;
}
#body-subject-container .subject {
background-color: blue;
}
where I want the first subjects
in the opening container to be red and the remaining subjects
in the body container to be blue.
If I shouldn’t ever use IDs in CSS selectors, what should I use instead?
Thanks for everyone’s advice. I decided to stick with using IDs since they are convenient and I am able to keep track of when I should use an ID and when not to. I got tired of the warning messages in the lint, so I just changed the source code and deleted some rules that display warnings like this.
4
ID’s are needed to be unique while classes tend to group several elements’ style together. I read somewhere it as this analogy :
<student id="JonathanSampson" class="Biology Calculus" />
<student id="MarySmith" class="Biology Networking" />
Student ID cards are distinct. No two students on campus will have the
same student ID card. However, many students can and will share at
least one Class with each other.
Moreover , ID elements tend to have higher priority over other selectors which makes it harder to reapply rules on them.
There was an stackoverflow answer regarding some JS function selecting only first occurence of same ID elements too (I’ll include link asap).
EDIT : try getting a bunch of elements by using getElementByID()
in js and you’ll notice what I was trying to say.
On the other hand , IMO you shouldn’t take csslint complaints too strictly on your css rules. Some of them are flawed by nature.
reference
3
I think the gist of the argument, for those that agree with it, is to use class
for css selectors instead of id
. This avoids unintended css precedence rules from kicking in.
If you know what you’re doing (re class vs id selectors), and it works for you, I wouldn’t change just for the sake of changing, though.
From http://csslint.net/about.html:
IDs shouldn’t be used in selectors because these rules are too tightly
coupled with the HTML and have no possibility of reuse. It’s much
preferred to use classes in selectors and then apply a class to an
element in the page.
2
The obvious answer to OP’s question – “What to use instead of IDs?” – is “Classes”.
Say I have a div on every page that contains my menu. Let’s also say I have some JavaScript that targets this menu, using it’s ID, which is …oh, I don’t know… id="menu"
.
The menu consists of an unordered list, and I use CSS to turn this from a normal bullet list into something that looks like a menu. So far, so conventional.
What Lint is saying is that, although I will only ever have one menu on my page, and although I wouldn’t want to apply menu-type styling to any other un-ordered list, and although I would want my menu styles to override any more general styles that I apply to all other un-ordered lists, it is bad practice to direct my styles to #menu
. Logically, therefore my div should look like:
<div id="menu" class="menu">My menu code here</div>
Naturally, I will want to be careful only ever to apply the ‘menu’ class in just one place on each page, because I will only ever display the menu once.
</sarcasm-mode>
While Lint’s suggestion – and the objection to selecting on IDs – may sometimes be justified, the above example shows, I think, that it is idiotic to apply as a hard-and-fast rule. Where we have content in the page that is ‘structural’ and genuinely once-per-page only – the header; the menu; the footer; etc – these elements are correctly identified by IDs, and correctly selected in the same way in our CSS.
There are many reasons to select by an id. I think the spirit of that message from lint is that you should primarily apply styling by classes.
Selecting by id can be the exception where your styling is shared across similar elements, except this one, or only this one.
You can use classes to act as an id, but I think thats probably evangelism. That’d be like the guys that insist to never use a table even when a table is perfectly appropriate.
This is what I generally stick to.
The main purpose, in my opinion, of having a separate css file is that it may be shared among multiple pages, which may use the styles in different ways. By using css classes instead of IDs, it is less restrictive, letting you not worry about duplicate IDs, while the lower specificity allows easier customisation of the style (either in another css file, or in the HTML head).
When writing css in the HTML head, I think using IDs is fine when you are referencing a particular element on the page. You may later decide that the css referencing IDs would be useful on another page. As long as you keep the css in the head, rather than inline, it should be easy enough to refactor it into a separate css file, replacing IDs with classes where appropriate.
Using ids is like using singletons, and singletons are not very good style. For prototype, yes, but in you’re trying to make things right, do not presume that “this kind thing will always be here once and only once” unless you know for sure. It’s more flexible to be prepare for 0 and many, not just for 1.
And of course, the CSS precedence is valid concern as well.
Eg. in your example there should be class="opening subject-container"
and class="body subject-container"
and you can select yourself if the style is applicable to all .opening
things or only to .opening.subject-container
, plus you can style things common to all .subject-container
s as well. Just a possible example.