Separation of Concerns Between HTML, CSS, and JavaScript

I review a lot of code. That experience has given me an interesting insight into the approach and thought process of many, many other developers. I often run across code where developers are mixing the responsibilities of their HTML, CSS, and JavaScript, making their code difficult to update or build upon.

The term separation of concerns has been around for a quite some time, more than 40 years, actually. In short, separation of concerns is a guiding principal in software development centered on the idea that programs should have distinct sections, with each section being responsible for its own concern.

A concern is a very broad term that can refer to just about anything that relates to a website or other piece of software. In this case, we’re going to be talking specifically about the roles and concerns that each language should have in the front-end stack.

By separating concerns between languages, you can drastically improve both the quality and maintainability of a project.

Separating HTML and CSS

A common issue I’ve encountered is developers using presentational classes in their markup. A presentational class is any CSS class that is used to define the look or feel of a particular element or component, but is not descriptive of the actual element or component.

For example, much of Bootstrap relies on presentational classes, which is especially evidenced in the grid system.

<div class="my-element col-lg-3 col-md-4 col-sm-6 col-xs-12">

Now, as you see, your markup is not only defining what your element is, but also how it looks. That’s CSS territory.

Rather than using presentational classes, why not use Sass mixins?

<div class="my-element">
.my-element {
    @include col-lg(3);
    @include col-md(4);
    @include col-sm(6);
    @include col-xs(12);
}

This approach accomplishes exactly the same thing, but keeps your HTML descriptive of the document and your CSS squarely in its own lane.

Separating CSS and JavaScript

Another common issue that I’ve encountered is CSS classes being too tightly coupled with JavaScript targeting and manipulation. Have you ever changed a class (say, to be more semantic) only to realize that it broke a bunch of other stuff?

There a couple of ways that I like to separate CSS and JavaScript.

First, when I target an element, I generally prefer to target an ID (if possible)… and I prefix that ID with js-. This will always signify to me, or anyone reading through my code, that an element is being targeted with JavaScript. I also never attach styles to the prefixed classes.

In practice, this would look like:

<div id="js-my-element" class="my-element">

or

<div class="my-element js-my-element">

Putting It All Together

With this approach your HTML, CSS, and JavaScript all play their own, clear roles. They do not overlap in their responsibilities and your code ends up being more semantic and flexible; making your application significantly easier to jump into and maintain.

Jon Bellah I am a full-stack web developer, speaker, and occasional writer. I live in the beautiful city of Denver, Colorado. I am currently employed as a Lead Front-End Engineer at 10up. You can follow me on Twitter at @jonbellah.
  • Pherdnut

    In 10 years, I have never felt it was necessary to split JS and CSS IDs/classes and have never been hurt or noticed any loss of flexibility in failing to do so. Hooks like IDs and classes are the point where everything meets in the DOM. It’s okay to share those and I would argue easier to know exactly what part of the HTML something is targeting when you’ve already looked at the other of the CSS or JS that intersect at that hook. If the need should arise to decouple one or the other, doing so should be trivial. Likewise moving both to another HTML element should be equally trivial. That does happen sometimes. That’s the advantage of having that shared point of separation.

    HTML is the skeleton we drape behavior and style on. Classes should describe what a given part of that skeleton is for, not who is going to act on it. The whole point of the hooks is to be the singular point we pull things together.

    A better example of violation of the separation principle in regards to JS/CSS IMO is using JS to set CSS styles directly for non-animation purposes when a simple class change would have done the job. This unnecessarily makes those properties hard to find for a web designer with minimal JS knowledge.

    I’ve agreed with you on Bootstrap since day 1 of encountering Bootstrap. The popular frameworks have similar problems.