If you learn any major bit of front end architecture philosophy from this series, learn this one. Just change classes. In this screencast we start going down a major rabbit hole of JavaScript only to stop, catch ourselves, and use CSS instead. When you are changing something visually, that is the domain of CSS. Not only is it good at it, it's typically more performant and maintains a healthy "separation of concerns" that makes for a long term healthy website.

After we came to our senses, we simply ended up swapping 1) the button text 2) a data-state attribute on the container.

$(".bigger").on("click", function() {
  var el = $(this);
  
  var module = el.parent();
  
  // Swap expanded state
  module.attr("data-state") == "expanded" 
    ? module.attr("data-state", "")
    : module.attr("data-state", "expanded");
  
  // Swap button text.
  el.text() == el.data("text-swap") 
    ? el.text(el.data("text-original")) 
    : el.text(el.data("text-swap"));
  
});

Here's where we ended up:

See the Pen quFCo by Chris Coyier (@chriscoyier) on CodePen

Yes, this video (and sentiment) is "just change classes!", and we're changing a data-* attribute here, but I think of that as the same thing. Sometimes I use data-* attributes just because I like them. I think of them like name-spaced classes, or classes with values. Arguably more useful in CSS than classes and they have the exact same specificity value.

Does that ? / : syntax look weird? If so, that's know as a ternary (or "conditional") operator.

The first line is a test, the next line (or the bit after the ?) is what happens if that test if true, the last line (or the bit after the :) is what happens if that test is false. Perhaps this helps:

// The boolean (true/false) test
module.attr("data-state") == "expanded" 
  // Do this if the test is true
  ? module.attr("data-state", "")
  // Do this is the test if false
  : module.attr("data-state", "expanded");

Don't avoid them just because they look weird, they can be more efficient (and ultimately read just as well, as long as you don't go nuts) as if/else logic.

Doug Neiner has a good article on the "just change classes" idea. Classes have so much power in CSS. You can hide/show things, move things, change the appearance of things, trigger animations... the sky is the limit. And the higher up in the "tree" (DOM) you apply the class, the more cascading power you have. A class change on the body means you can control anything on the entire page with a single class. And all with a very tiny amount of JavaScript.

Once you buy into this you'll be a happier developer.

Comments

  1. Noor Hammad
    Permalink to comment#

    Great article on maintaining separation of style and behaviour by changing data attributes instead of classes:

    http://toddmotto.com/stop-toggling-classes-with-js-use-behaviour-driven-dom-manipulation-with-data-states/

Leave a Comment

Posting Code

We highly encourage you to post problematic HTML/CSS/JavaScript over on CodePen and include the link in your post. It's much easier to see, understand, and help with when you do that.

Markdown is supported, so you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences like this:

```
<script>
  function example() {
    element.innerHTML = "<div>code</div>";
  }
</script>
```

We have a pretty good* newsletter.