In HTML5, the data-* attributes were codified, and this is a really nice thing for building applications. They are an app-defined namespace to attach any sorts of custom data to your HTML attributes. For example, a div responsible for displaying a User object might have an attribute like <div data-user-id="5123">…</div>, which allows us to better bind our DOM to our application model. They can even be used in stylesheet selectors, so I could make a styling rule for div[data-user-id].

I’m not the only one who thinks they’re a nice feature. Eric W has a co-worker who’s come up with a very… unique way of using them. First, he has the following Django template:

{% for cat in categories %}
        <a href="#" {% if shopType ==|slugify %}class="navOn" {% endif %}data-type="{{|slugify }}" data-id="{{ }}">{{ }}</a>
{% endfor %}

Which generates links like: <a href="#" data-type="housewares" data-id="54">Housewares</a>

Obviously, since the href points nowhere, there must be a JavaScript event handler. I wonder what it does…

$('.shop-nav a').unbind('click').click(function(e){
    var page = $(this).data('type');
    window.location.href = window.location.origin+'/shop/'+ page;
    return false;

This is one of my favorite classes of bad code- the one where a developer uses a new feature to completely reinvent an old feature, badly. This JavaScript uses the data-type attribute to hold what should actually be in the href. Instead of having real navigation, we hijack the click event to force navigation. The entire JavaScript could be replaced in favor of a link like this: <a href="/shop/housewares">Housewares</a>.

Maybe they need data-type because there’s a CSS rule that styles it?

[Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!