Why Have People Started Deeming it Necessary to Separate JS hooks from CSS hooks in HTML?

Edit: Point of clarificatioon, IDs and classes as separate hooks is just one form of the applied idea in question which is to never use the same hooks for CSS as you do in JS. I’ve also seen people want things like js-combo_box and css-combo_box as classes on the same element.

This is one I’ve started running into more and more in recent years. People wanting to only use IDs for JS and classes for CSS. Or they don’t want JS to touch classes and IDs at all and rely on things like HTML5 data-attributes hooks (which is and will probably remain the slowest way to actually find an element even in modern browsers).

In 5+ years of occasionally heavy-duty/insane-environment client-side web development including one very large totally messed up e-commerce retail operation where HTML nobody was even working with would mutate because we had 200 offshore devs of varying levels code illiteracy (completely on the low end, not kidding) jumping up and down on the back end codebase with no source control, I’ve never run into an issue where JS and CSS targeting shared attributes in the HTML caused any kind of maintainability or ease of modification problem for me. I guess I’m wondering what is informing this perceived need and whether I’m missing something that comes up for a lot of people?

Isn’t HTML via selectors and the DOM API effectively the point of abstraction that ties everything together? Why would JS and CSS concerns sharing the same attributes there ever cause a problem?

5

Maybe you notice that because, as you said it yourself, you have to work with inexperienced programmers.

In practice, the distinction you observe doesn’t exist. Frameworks, by the way, discourage such distinction.

For example, jQuery encourages pretty well to use selectors in a general way, which means that you use IDs to target a single element and classes to target multiple elements.

In the same way, a not totally retarded developer would quickly notice (learn) that classes are bad candidates for unique elements on a page: of course, you can replace all IDs by classes in both HTML and correspond CSS, but it would make things slightly… let’s say unreadable, if nobody cares about performance.

As for the inexperienced programmers, they may tend to do strange things. It took me a few weeks to explain to one fellow colleague that:

<div id="entry">Some text here</div>
<div id="entry">Some other text</div>

is wrong, because IDs are unique. Take one beginner who have just read an article explaining how to use classes in CSS and another article about data- attributes in jQuery, and you easily understand why this beginner starts to use classes for CSS and data- for jQuery selectors.

6

Using classes for JS makes perfect sense.

Classes, like their name suggests classify DOM elements.

For example, if I had a list of items

<div class='item'>Item1</div>
<div class='item'>Item2</div>
<div class='item'>Item3</div>
<div class='item'>Item4</div>

It would make perfect sense to select them with the following selector .item instead of assigning an ID to each of them.

More-over, in many commonly used JavaScript libraries and code bases class selectors are used for selecting elements. I’ve seen it used in production code many times and it seems like acceptable practice.

The only beef people have with class selectors over ID selectors is that ID selectors are faster (perf here). Most of the time I have found that doesn’t really matter.

1

Okay, a complete flip-flop of what I was going to write, based on two specific parts of the question:

we had 200 offshore devs of varying levels code illiteracy (completely on the low end, not kidding)

and

Why would sharing attributes there ever cause a problem?

I have run across something similar to this in the project I’m on at work right now. What I was dealing with is what happens when the unskilled programmers tie functionality entirely to classes, without thinking about consequences or maintainability. (That is, they were reusing classes just because they’re there and happen to be on all the right elements)

What you’re looking at is a simple, sledgehammer-like way to enforce separation of concerns on the unskilled programmers.

If functionality is strictly tied to IDs, and design to Classes, then they can change both without having to worry about the other. This is especially helpful from a design standpoint – as long as they include all the requisite IDs for the Javascript functionality, they’re fine.


That said, I strongly disagree with this approach (see other answers for why). It’s extremely limiting to even the halfway-decent programmers and almost always requires extra bookkeeping javascript to keep track of #foo_1, #foo_2… when .foo would have sufficed.


EDIT @jmoreno has pointed out that I missed the clarification paragraph at the top, so now parts of my original answer seems much more appropriate. Personal anecdote time!

See, at work, we have a library written in Django+JS+CSS, shared among a large chunk of our products. It was written in a very specific way, meant to be highly configurable, and included into various projects by way of a Django templatetag with arguments used for configuration of the JS.

Unfortunately, because the JS and CSS was tied together by sharing classes, it meant that certain features that looked like entirely separate options could only work if both were specified, or both were left out. And they were mutually exclusive with a third. Any other combination caused the JS to error out, because it would make assumptions about which classes existed in the generated HTML.

We needed options 2 and 3, but not 1. This was unfortunate, to say the least: For example, Option 1 was including CSS-styled classes for Option 2’s JS (which it was only using because, as described above, the classes were already there so why not?). So if you used Option 2 without Option 1, there would be so much breakage styling-wise that it became unusable.

I have been beating that JS into submission on and off for nearly three months at this point, just making all 3 options independent of each other and ironing out the bugs.

This extra work shouldn’t have been necessary, and wouldn’t have been if the whole thing was well-written initially. Forcibly separating which classes the JS and CSS act upon would have helped to prevent Option 1 and Option 2 from getting tied together back when it was first being written.

That said, it’s generally not possible to be 100% on this rule. One of those is a simple .loading class that gets added/removed as necessary.

7

As someone who’s adopted this pattern, one of the biggest reasons I’ve done it is that I feel it makes the markup a little more semantic. If I’m working on changes that touch an element with a .js- class on it I know that there should be some JS somewhere that is either listening to this element or operating on it. Knowing that the JS is using this element means that I’m extra careful about how I change it.

The same could be said about using a data attribute except that you could argue that it goes one step further by separating the JS from the CSS by not using id’s or classes(I don’t typically use data attributes as JS selectors but I’ve seen it).

First, I don’t think that separation is absolute. id’s for example are unique to a document and so it makes sense to use them for both CSS and JS. For classes though, there are good reasons for these to be separate.

The basic issue is that CSS and JS implement what you might think of as cross concerns. CSS implements layout, display, and typography, while JS implements behavior. Or at least this is how they are most often (and I think, best) used. You can think of these as orthogonal concerns or dimensions, and so individual DOM objects may need to be placed, not in a line of functionality, but rather in a two-dimensional area where the dimensions are display and functionality.

Again if you want to look up a single element, CSS and JS may both do this by ID, but if you want to look up a group you probably don’t want to tie display and behavior together too tightly.

This is a general issue and I don’t think it depends on how experienced your developers are or what tools you are using. As long as the concerns are different you may want to be able to classify elements according to multiple types of concerns and this is one way this happens.

In 2020, I will tend to do something like the following.

Imagine an accordion menu:

<nav class="mainMenu">

  <ul class="mainMenuList">

  <li class="mainMenuSection">
    <strong class="mainMenuSectionTitle">Site Section A</strong>
    <ul class="mainMenuPageList">
    <li class="mainMenuPage">Page A1</li>
    <li class="mainMenuPage">Page A2</li>
    </ul>
  </li>

  <li class="mainMenuSection open" data-main-menu-section-state="open">
    <strong class="mainMenuSectionTitle">Site Section B</strong>
    <ul class="mainMenuPageList">
    <li class="mainMenuPage">Page B1</li>
    <li class="mainMenuPage">Page B2</li>
    <li class="mainMenuPage">Page B3</li>
    <li class="mainMenuPage">Page B4</li>
    </ul>
  </li>

  <li class="mainMenuSection">
    <strong class="mainMenuSectionTitle">Site Section C</strong>
    <ul class="mainMenuPageList">
    <li class="mainMenuPage">Page C1</li>
    <li class="mainMenuPage">Page C2</li>
    <li class="mainMenuPage">Page C3</li>
    </ul>
  </li>

  </ul>

</nav>

(To clarify, data-main-menu-section-state="open" is the open section of the accordion, which, when opened by the visitor, unfurls downwards until all the links from Page B1 to Page B4 are fully revealed.)

The argument against this would be that, since both:

  • .open
  • data-main-menu-section-state="open"

indicate the accordion section which is open, only the first is necessary.

But, this kind of setup where:

  • classes represent CSS hooks; and
  • HTML5 Custom data-* attributes represent JS hooks

means I can have some confidence (not least if I am coming back to a project that I last worked on months before) that I can remove or change the name of any particular class when refactoring the document’s Presentation and it will never disable any JS Behaviour currently applied to the same element.

Furthermore, I may deploy the generically-named class .open elsewhere in the document, leading to two similar but not identical style-blocks in my stylesheet, such as:

  • .mainMenuSection.open
  • .headerMenuSection.open

in full confidence that the new elements that I append the class .open to, won’t then also immediately adopt javascript behaviour which I don’t need or want them to have.


In Summary:

When I’m refactoring CSS, I don’t want to also have to be constantly thinking about whether this is going to result in any unwanted javascript side-effects.

And when I’m refactoring JS, I don’t want to also have to be constantly thinking about whether this is going to result in any unwanted CSS side-effects.

See also: Uncle Bob Martin’s Single Responsibility Principle

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật