2

I sort of understand unobtrusive javascript. Even in my CSS now I hardly ever use classes or id's because I like clean, easy to read, uncluttered html files. For example, why use this:

<body id="anchor" ontouchstart="">
  <nav id="nav">
    <div id="design" class="option">
      <p class="vCenter">design</p>
    </div>
    <div id="function" class="option">
      <p class="vCenter">function</p>
    </div>

    <div id="rule"></div>

    <div id="advanced" class="option">
      <p class="vCenter">advanced</p>
    </div>
  </nav>
</body>

When I can use this:

<body>
  <nav>
    <div>
      <p>design</p>
    </div>
    <div>
      <p>function</p>
    </div>  
    <div></div>
    <div>
      <p>advanced</p>
    </div>
  </nav>
</body>

And then use the very powerful CSS3 selectors to access all of my elements. Or I could use JavaScript to give these elements classes and ids. Am I too obsessed with clean code? Or is this a more future proof, cleaner way of developing?

4
  • "Anecdotally, some selectors are difficult to implement efficiently for browsers... The thing that is really fast is using class names or IDs..." (CSS: When to use which selector)
    – gnat
    Apr 22, 2016 at 16:38
  • @gnat As stated, I could also give class names and ids to all of my elements through JavaScript, is this necessarily bad? Apr 22, 2016 at 16:39
  • 1
    crosspost: stackoverflow.com/questions/36798700/… Apr 22, 2016 at 17:50
  • @carb0nshel1 FYI, cross-posting is generally frowned upon as most of the time the question is close-worthy on at least one of the sites, so that creates extra moderation work, and even if it does fit both sites it still splits the answers and comments to a single question across two different sites so anyone interested in the question has to visit both pages to get the full picture.
    – Ixrec
    Apr 23, 2016 at 11:32

2 Answers 2

13

This seems like a very bad idea to me. defining css rules for classes and adding those classes to the html is a great way to make your css reusable. The way you're suggesting, with a complex selectors, sounds like a recipe for mangled stylesheets. Sure, your html is clean as a whistle, but now the css is a pain in the butt to maintain.

Consider:

.centre-box {
    /* your rules */
}

Vs

body div > div:nth-of-type(3) > div {
    /* your rules */
}

Then next week you you add a div above the box you want to be centred, and it's broken. To fix it, you have to find the tangly css rule that targeted your centre-box before, and change it to be something new. And all of this hassle so that your html looks cleaner?

More up front time, higher maintenance cost, no extenuating circumstance that makes it necessary. End of story.


Addendum

Why do complicated css selectors even exist?

Sometimes you want to style more than just one element. Consider this example from bootstrap, a very popular css framework. (Note: It's written in less, which compiles to css. It supports nesting, so all you need to know when reading the example is that foo { bar { /* rule */ } } in less is foo bar { /* rule */ } in css.)

Example: navbar source uses the > selector (direct child selector) to style direct children of the .navbar-brand element.

But in this case, you use a class with a meaningful name to relate the css rule to a part of the DOM, and you use the fancy selectors to style the child elements of that class.

What about doing it in JavaScript?

This seems like a non-solution for me too... to convert from using classes and ids and your old stylesheet to doing it with JavaScript, you'll keep your css the same, simplify your html, but add an entirely new JavaScript file which must either (1) use complex selectors with jQuery, so it's as much of a rat's nest as the crazy selector stylesheet option, or (2) use JavaScript without jQuery to traverse the DOM and attache elements as needed.

(1) is just as bad as putting it in css, and (2) is worse than (1) in my opinion because you'll basically have to duplicate your DOM structure in your JavaScript file (just in a different format, but same info), so you still have a DOM with ids and classes, it's just written in JavaScript. That's a lot more complexity.

So what is unobtrusive JavaScript?

I won't give a full treatment of it here because there's lots on Google if you're looking for details. But the key point as it relates to this is that unobtrusive JavaScript is that you don't want your JavaScript to intrude on your html. This relies on using ids and classes to identify which elements to attache JavaScript behaviour to. Unobtrusive JavaScript says: use ids and classes to attach events to elements instead of inlining the JavaScript events.

In a nutshell

Css classes with meaningful names are the current best way to associate a set of css rules with a portion of the html that you want to modify. This is the current convention, and the alternatives that you're suggesting add complexity and reduce maintainability.

5
  • Great answer, but there's still a few issues I'm thinking about: Why do these complex CSS selectors exist? Second issue - to avoid a "mangled stylesheet" why not just assign all of your CSS ids and classes in a separate JavaScript file to keep both the html and CSS clean? Apr 22, 2016 at 17:15
  • I don't think that's a great option either, since it adds unecessary complexity. Plus, you'll still have to use complicated selectors with jQuery to find elements to add classes to, or in vanilla JavaScript you would have to manually traverse the DOM to modify elements. So you still have the same problem as with the css, it's just now a JavaScript issue. Apr 22, 2016 at 17:22
  • As for why they exist: they have a purpose - sometimes you do need to do complicated things. For example, styling a nav bar drop down, the parent ul and lis are to be styled to be always shown, and the dropdowns (nested uls) are styled differently. nav > ul { /* top level only */ } nav li ul { /* any submenu * / } Apr 22, 2016 at 17:26
  • Another pro for ids is automated testability - it may clutter your HTML a bit, but in some situations it's much easier and robust.
    – Andy
    Apr 22, 2016 at 17:52
  • That's ... a truly terrible approach to JS, since the classes and ids are effectively global mutable state.
    – DeadMG
    Apr 22, 2016 at 18:02
0

The answer is that you should probably not be spitting out raw HTML and then attaching JS and CSS to it.

The core problem is that the ids and classes are basically global mutable state, since anybody can mutate the DOM with any classname or id for an element. Alternatively, they can read or mutate your state easily by looking it up by ID or class and then apply random styles or random mutations through JS.

The whole thing becomes one giant glob of ids and classnames and 99 selectors and a bitch is theoretically not one but I wouldn't be surprised. You can't change anything without having to check the whole damn codebase.

Instead, it's a lot better to put it all in one place with a technology like React. You basically just don't need DOM element ids anymore and classnames are almost completely redundant too. You can keep all the logic about a given piece of HTML in one place without stupid global state.

6
  • Rotfl. Great answer. The Jay-Z reference did it for me. +1, +99 if i could. Apr 22, 2016 at 18:11
  • My answer contains serious technical advice as well as a Jay-Z reference
    – DeadMG
    Apr 22, 2016 at 18:16
  • what do you mean by "You can't change anything without having to check the whole damn codebase" Apr 22, 2016 at 20:18
  • Well, anybody anywhere can have a selector that references any id or classname, so you can't know that changing it is safe without knowing in advance that nobody else did that. So you must know the whole codebase before you can make the change.
    – DeadMG
    Apr 24, 2016 at 21:45
  • That's what grep or your IDE is for - as long as you're not assembling ids or classes dynamically in your code a simple text search will find any reference to it. "Searching the whole code base" is a one line command and seconds of waiting. To say that this issue is so huge that one should never use plain old html and css for a website and should instead use a framework seems a bit extreme. Apr 30, 2016 at 12:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.