56

Lately I've been wondering what the best way to go is to perform javascript actions on multiple elements.

The way I see it there are 2 possibilities:

  • Either I add a css class to my elements, which doesn't necessarily correspond to any existing css rules: <div class="validation-required"></div>
  • Or I use a data-attribute like so: <div data-validation-required></div>

In my IDE (Visual studio 2012 using R#), if I use the first method, I get a warning saying I shouldn't use css-classes which aren't defined. Which makes me believe this might not be the best idea anyway. However, this is the method I've most-often seen used, though this might just be a relic from days before we could use the data- attribute.

So my question is pretty simple, which way should I go to simply "tag" an element for further processing?

Thanks for any answers

PS: I realize this question might be prone to subjective opinions, though I do hope there is a concensus on what to use in modern-day browsers.

PPS: I've done a search on this matter, but most questions are about performance, which isn't my primary concern for one-off situations.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Kippie
  • 3,760
  • 3
  • 23
  • 38
  • @karaxuna Any specific reason why you prefer this? Or is it just personal taste? – Kippie Jun 19 '13 at 07:13
  • I can't tell any specific arguments. But i think that css class is for assigning styles and data attributes are exactly for assigning data to element. It's more natural way for me – karaxuna Jun 19 '13 at 07:16
  • 3
    +1 to classes. Classes already act as boolean flags of a sort while attributes generally have values associated with them. Also, selecting by class is faster. – zdyn Jun 19 '13 at 07:24
  • +1 : I like deep infrastructural questions – CME64 Jun 19 '13 at 07:26
  • 1
    I think data attributes are for attaching data to a node, not for grouping semantic elements together, what you are doing is associating different elements semantically and wanting to query for them. Class names allows you to do that. – Ruan Mendes Dec 10 '13 at 19:52

4 Answers4

28

According to W3C

data-*

Custom data attributes are intended to store custom data private to the page or application, for which there are no more appropriate attributes or elements. These attributes are not intended for use by software that is independent of the site that uses the attributes.

class

The class attribute has several roles in HTML: As a style sheet selector (when an author wishes to assign style information to a set of elements). For general purpose processing by user agents.

The bold text above is the autoritative assurance that it is ok to use class attribute without its definition in CSS. The warnings from VS 2012 about that are overzealous.

If you use class attribute, you can benefit from native getElementsByClassName searching (with O(1) time complexity) and classList object for toggling, adding and removing class. There's nothing like getElementsByAttributeValue. There is relatively slower Element.querySelectorAll('[data-attr="value"]') ref See Oliver Moran's comment. It has O(n) time complexity.

On the other hand, if you need to store multiple data, you can use dataset attribute. So if you want searching or if the data affect the look of the element, I would use class. If you need to store multiple data, the data would be more appropriate.

In your particular case I would consider required or pattern input attribute (since HTML5 most of input validation moved from JS to HTML). To style such elements, CSS selectors use the same syntax as querySelectorAll.

Jan Turoň
  • 31,451
  • 23
  • 125
  • 169
  • You could use the `data-*` selector in jQuery to get a list of all elements that use *that* data-attribute – painotpi Jun 19 '13 at 07:30
  • 3
    @badZoke This question is not about jQuery, so your note is OT. My point was about native support. Frameworks should be used for particular architecture. If any JS framework wants to add some general pseudonative feature (like data-* selector), it just means that the creator doesn't understand some principles behind. – Jan Turoň Jun 19 '13 at 07:51
  • In the end I've selected this answer based on the W3C criteria specified. Nowhere does it mention a *requirement* for class to resolve into a specific style. Especially "For general purpose processing by user agents." makes me feel I can use this, rather than an empty data attribute. – Kippie Jun 19 '13 at 08:20
  • 9
    "There's nothing like getElementsByAttributeValue, you need to iterate." Yes there is. Try `document.querySelectorAll(tag[data-attr="value"]);` and it will select all `` tags. See https://developer.mozilla.org/en-US/docs/Web/API/Document.querySelectorAll – Oliver Moran Dec 10 '13 at 00:04
20

Best way to test these things is to search for a test suite on jsperf.com

Here is the one you are interested in: http://jsperf.com/id-vs-class-vs-data-attribute

The most efficient selector is to use classes.

This is probably a consequence of classes being used more for selection, so browsers will optimize that more?

JsPerf.com results for selection based on ID, Class or attribute

Berty
  • 1,081
  • 1
  • 18
  • 49
  • 2
    It doesn't matter in most cases. I've just tested it on newest Chrome, id has 1300000 ops/s, a data-id 90000 ops/s. Still, at 90000ops/s, it only takes 0.01ms to execute. In a typical example where you want to select an element by data attribute, you only do this once at a time. – Maciej Krawczyk Jun 16 '17 at 10:39
  • 1
    please dont forget you are testing this on a fast machine. some people use slow computers or mobile devices. so 14 times as fast on an old android tablet from 2010 might make a diffrence. – jurrieb Sep 11 '19 at 08:51
15

If you merely want to associate "values" to DOM elements for computational purposes then data-attribute is the way to go since,

anything that is "data-" will be treated as a storage area for private data (private in the sense that the end user can’t see it – it doesn't affect layout or presentation)

Also, jQuery provides the .data(), which makes life easier so you don't have the trouble of using the [data-*] selector.

If you are providing a class name then, considering semantics, it should have some style associated with it.

John Resig has written about data-attributes

painotpi
  • 6,894
  • 1
  • 37
  • 70
  • I understand your point, but in my scenario, I'm not storing any data. I'm using an empty data-attribute as a way to mark my element for my script to pick up. Does your answer still count if I use it for this? – Kippie Jun 19 '13 at 07:16
  • Yes, since you're still using it as an access point for your script and nothing else (not for styling and/or presentation). Also, you are *storing data* (data which tells the script to pick it up). – painotpi Jun 19 '13 at 07:18
1

If you decide to use the data-* approach, specs for use of custom data elements -- and example usage -- are given here:

W3 spec on embedding custom non visible data with the data attribute

Here's a short, relevant excerpt:

3.2.3.8 Embedding custom non-visible data with the data-* attributes A custom data attribute is an attribute in no namespace whose name starts with the string "data-", has at least one character after the hyphen, is XML-compatible, and contains no characters in the range U+0041 to U+005A (LATIN CAPITAL LETTER A to LATIN CAPITAL LETTER Z).

All attributes on HTML elements in HTML documents get ASCII-lowercased automatically, so the restriction on ASCII uppercase letters doesn't affect such documents.

Custom data attributes are intended to store custom data private to the page or application, for which there are no more appropriate attributes or elements.

Dan H
  • 14,044
  • 6
  • 39
  • 32