I did a guest lecture Tuesday night at Ignition, a coding school run by Spark Boulder that prepares students for their first coding internship. It was fun and I learned a lot about how to improve lecturing abilities. I also got a lot of good questions and one question that I didn’t think I answered well enough, so I thought I’d elaborate.
This is a great question.
IDs Can Only Be Used One Time On A Page
No big deal. Right? I guess.
The complexity isn’t that bad and you still get the benefit of separating behavior and presentation, but what if you need to target something inside the repeating element. A good example of this is an accordion; you know, a list of items (siblings) that expand on click and collapse when a sibling is clicked. With jQuery, you’d add a click event to an item where [id^=element]. The element that is clicked can be used to find it’s sibling, but if you’re only using IDs, you’d also have to add another cumbersome, iterating ID (e.g. id^=sibling) to the sibling (#sibling01, #sibling02) .
Some people like complexity, but let’s say for some reason you can’t loop the HTML to easily make the IDs unique; for instance, when you’re not using real data. Prepare to waste time. And when the client asks to change the order of the elements? More time gone. And what about when your function stops working all together because you had two identical IDs? Not good. And what about when you accidentally bind #elementary and #elemental when you only thought you were binding #element+number. Yes, another debugging problem.
The fact that you can only use IDs once means that your code is more complex and difficult to maintain.
You Can Only Add One ID Per Element
Let’s say I add some complex animation to an element by ID. Later, I realize I want to add some unrelated analytics to that element as well. I could bind it to the same ID, but that could pose a problem if it also needs to be added to other elements on the same page. With IDs, there is no way I can add another selector to keep these unrelated behaviors separate.
I Like To Write Stuff To Be Repeatable
Let’s say I write a block of code using an ID and then I decide I want to repeat it later. If I used IDs I’d have to copy and paste the HTML, make the IDs unique, and go back to update the JS. Why not just write it to be repeatable the first time? You can’t do that with IDs.
Presentation And Behavior Are Often Interconnected
Good website design often includes changes to style based on the state of an element (open, closed, focused, clicked, etc.). An extremely easy way to do this is to use the jQuery functions .addClass(), .removeClass(), and .hasClass(). By its very nature, this feature requires that we manipulate classes with JS.
Many times, presentation and behavior are interrelated and separating them in some cases isn’t good.
I’ve worked on several big sites. These were built and maintained by many developers (in house and out) and they have a lot of moving parts. When adding and changing functionality, these sites have many files that affect the elements of any page—sometimes files on top of files.
A Proposed Solution
So, what if we all agreed on a solution that gets many of the benefits of using IDs while still solving the problems I introduced above? Would it be adopted? Probably not, but here goes anyways.
Whenever possible, we separate behavior and presentation by using a naming convention to identify classes that are only used as JS selectors. For instance, we add .js to the beginning of selectors only used for behavior (e.g. .jsElement, .jsSibling, etc.).
This simple rule would solve all our problems. What do you think?
I’m sure there are things I didn’t take into account above. I’d love to hear your comments below. In an attempt to rebuttal some of the easy responses to my proposal above, I’ve included a couple thoughts here.
I know someone is thinking, “but classes are slower selectors than IDs.” Yes, but I’d argue it is negligible. You’re still talking milliseconds. I heard someone say once that when you write code, write it as elegant as possible even if it occasionally sacrifices speed. Then, go back and rewrite if only if necessary (although it isn’t most of the time).
And others are thinking, “but data elements as JS selectors would be better.” The problem with data elements is that you’ll always have instances when behavior and presentation are interconnected. Why not just have one simple rule that solves all our problems, rather than using data elements except when we don’t. And data elements are slower. :)
What do you think? Comment below.