As we web developers transition from building web sites to building web apps, there are a few new techniques and best practices that need to be considered. The following lessons apply to any JavaScript framework, but I’ll be discussing them in the context of Meteor apps because that’s what I use day to day.

1. Avoid using href=”#”

We’ve all done it. We need something clickable that triggers an action. So we throw in an anchor element, style it to look like a button, and call it a day. But the purpose of an anchor element is to link somewhere, and “#” isn’t exactly somewhere is it? If only HTML gave us a general purpose element for clickable UI elements. You know, a button…

Enter the long forgotten <button> element.

In the past web developers have avoided using the <button> element because of it’s unpredictable appearance and behavior in various browsers. But with the combination of modern browsers and CSS frameworks like Bootstrap and Foundation, the <button> element is finally a viable option. So now instead of linking to nowhere:

<a href="#" class="btn btn-default">Do Something</a>

We can instead write:

<button type="button" class="btn btn-default">Do Something</button>

A few more keystrokes, but in my opinion cleaner and more semantic.

Now you may be saying “But my designer really wants a link! You know, just normal text with an underline!”. Well you’re in luck! Bootstrap provides a .btn-link class for this exact reason. Just add .btn.btn-link to your <button> and you’ll have a semantic, clickable element that looks like a normal link.

2. Don’t reference class or id attributes in your JavaScript code

This might be a controversial one, as it is even more prevalent than our href=# friend. Every Meteor or Backbone.js app I’ve ever seen has had event handler code that looked like this:

"click .remove-link": function(event) {

event.preventDefault();

this.remove();

}

With accompanying markup in the template:

<a href="#" class="remove-link">Remove this</a>

This works fine, right? What’s the problem?

Classes and Ids are for styles

I’m going to suggest that class and id attributes only ever be used to style an element, never to attach behavior. Why is this important? A few reasons:

Separation of concerns

A general good practice in software development is separation of concerns. Like most things in programming this is a complicated sounding term that has a simple meaning: each piece of code should have only one responsibility. There’s no reason we shouldn’t extend this best practice to our CSS as well.

2. Maintainability

Here’s a more tangible benefit with an example: You hire an intern to work on your templates and CSS. He starts refactoring, moving elements around, changing class names, etc — and all the sudden your app is breaking. Event handlers that were attached to specific class names are no longer firing. Why should changing the way your app looks, effect the way your app works? Because you’ve coupled your app’s behavior with it’s presentation.

3. Readability

When scanning a template full of ambiguous class names like .remove-link, it’s not immediately apparent which elements have behavior attached to them and which elements are strictly presentational. This can be a small thing, but when it’s late on a Friday and you’re tracking down a pesky bug, these seemingly small things add up.

So what do we do instead?

HTML 5 introduced the concept of custom data attributes, which I think are a perfect solution for this use case. Rather than specifying an element’s behavior with a class or id attribute, we can instead write:

<button type="button" class="remove-link" data-action="remove">Remove this</button>

And in our event handler:

"click [data-action=remove]": function(event) {

event.preventDefault();

this.remove();

}

Now our designer can change the .remove-link class without affecting our app’s behavior. And when scanning our template we immediately know that this element has style rules attached to it’s .remove-link class, and behavior attached to it’s data-action attribute.

Also, note that in my event handler I didn’t specify an element type, I only specified the data attribute: [data-action=remove]. This separates our concerns farther and would even allow a designer to change the type of element being used.

3. With Less.css power comes more responsibility

Here’s more good advice from Ryan Florence:

CSS pre-processors like Less and SASS are great, right? Well, mostly. But there’s one feature in particular that I’ve found particularly dangerous, and that’s “nesting”. Here’s what I would consider a valid use case for nesting:

a {

color: blue;



&:hover {

text-decoration: underline;

}

}

But when taken too far, as I often see it done, you can end up with an unmaintainable rat’s nest (pun intended) of CSS that looks like this:

.sidebar {

.body {

ul.actions {

li:last-child {

a {

border-bottom: none;

}

}

}

}

}

In this case our CSS is dependent on the structure of our HTML markup. If we move ul.actions outside of .body, we have to change the nesting of our CSS. If we want to use ul.actions inside another div elsewhere on the site, we’re unable to. Our CSS and HTML are tightly coupled, and we don’t have a good separation of concerns.

Reject the cascade

As Ryan said, we should “reject the cascade”. But what does that mean exactly? Without getting too deep into it, the basic idea is to not specify style rules based on the hierarchy of your markup, but to instead give each element a unique, descriptive class name.

So in lieu of:

.sidebar {

.body {

ul.actions {

}

}

}

Our CSS would look like:

.sidebar {} .sidebar-body {} .sidebar-actions {}

Now it’s immediately apparent that all three classes are related to the sidebar element, while at the same time each of the classes can be used independently of each other, and we can change our HTML structure without having to worry about our CSS structure.

If you like this technique, I recommend you take a look at SMACSS and BEM which take this concept even farther to really help you write clean, maintainable CSS in large projects.