03.03.13

Keep your HTML in your HTML

Posted in Uncategorized at 11:25 am by danvk

I sometimes see code like this to generate DOM structures in JavaScript:

var div = document.createElement("div");
div.innerHTML = "<div id='foo' onclick='document.getElementById(\"foo\").style.display=\"none\";' style='position: absolute; top: 10px; left: 10px;'>" + content + "</div>";
document.body.appendChild(div);

This style gets very confusing very quickly. The issue is that it uses JavaScript to write HTML, CSS and even JavaScript inside HTML!

The key to untangling these knots is to remember this rule:

Keep your HTML in your HTML, your JavaScript in your JavaScript and your CSS in your CSS.

Here’s how I’d rewrite that snippet with this in mind:

HTML:

<div id='foo-template' class='foo' style='display:none;'>
</div>

CSS:

.foo {
  position: absolute;
  top: 10px;
  left: 10px;
}

JavaScript:

var $foo = $('#foo-template').clone().removeAttr('id');
$foo
  .on('click', function() { $(this).hide(); })
  .text(content)
  .appendTo(document.body)
  .show();

The idea is that JavaScript is a really terrible language for building DOM structures. You can use either the innerHTML technique (in which case you run into quoting issues) or the DOM manipulation APIs (which are quite cumbersome and verbose).

HTML is a great way to define DOM structures! So define your DOM structures there, even the ones that you’ll add dynamically. You can use jQuery’s clone method to make copies of them that you fill out before adding them to the page.

CSS is also a great language for defining styles, so why put them inline in your HTML? Just use a class and move the styles into your CSS.

And really, do you want to write JavaScript that writes HTML that includes JavaScript?

You can see a real-world example of this technique in OldSF’s HTML, JS and CSS.

3 Comments

  1. Charles said,

    March 3, 2013 at 2:13 pm

    This also looks like a place to try out the Html5 template tag, especially if you use the structure repeatedly. However, it’s only supported in Chrome right now.

  2. Kenny said,

    March 3, 2013 at 8:13 pm

    I’m a big fan of Closure Templates (aka Soy Templates): https://developers.google.com/closure/templates/

    I’ve never tried to use them outside of Google, but from glancing at the documentation it doesn’t look that bad. (Famous last words)

  3. danvk said,

    March 3, 2013 at 8:23 pm

    I’d like to keep Java’s creepy tentacles out of web dev if I can. handlebars.js looks interesting (based on Google’s CTemplates): http://handlebarsjs.com/

    If you’re living in the Java world, JSTemplate is the way to go: https://code.google.com/p/google-jstemplate/