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)
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.
.foo would have sufficed.
@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.