A complete guide to data- * HTML attributes

We present to your attention a translation of the article on the use of attributes data-*. These are attributes that can be used for convenient storage in standard HTML elements of various useful information. This information, in particular, can be used in JavaScript and CSS.



General information


HTML elements can have attributes that are used to solve a variety of problems - from providing data to assistive technologies, to styling elements.

<!--  `class`      CSS,  `role`    -->
<div class="names" role="region" aria-label="Names"></div>

It is not recommended to create your own attributes, or apply existing attributes in ways that they are not designed for.

<!-- `highlight`   HTML--->
<div highlight="true"></div>

<!-- `large`      `width` -->
<div width="large">

This is bad for many reasons. HTML is incorrectly generated. And although this may not have real negative consequences, this deprives the developer of a warm feeling caused by the fact that he creates valid HTML code. But the main reason you should not do this is because HTML is a language that is constantly evolving. As a result, if a certain attribute is not used in the language today, this does not mean that nothing will change in the future.

True, if someone needs to use such attributes, he has a completely normal way of doing this. It is about creating your own attributes, the names of which begin with a prefix data-. You can easily work with these attributes, applying them the way the programmer needs.

Syntax


The ability to create custom HTML attributes and write data to them can be extremely useful. This, as you know, is possible due to attributes data-*. It is for this that such attributes are intended. It looks like this:

<!--      -->
<div data-foo></div>

<!-- ...     -->
<div data-size="large"></div>

<!--      HTML,    HTML-, , ,      -->
<li data-prefix="Careful with HTML in here."><li>

<!--   -      -->
<aside data-some-long-attribute-name><aside>

These attributes, precisely because they always start with a prefix data-, are often called attributes data-*or data attributes. When forming the names of these attributes, the word comes first data, then dash ( -), and then the rest of the name, arranged as the developer needs.

Can I use an attribute named data?


Here is a sample code that uses an attribute named data:

<div data=""></div>

An attribute with this name will probably not hurt anyone, but its use will not allow you to use JavaScript tools, which we will discuss below. In this example, the developer, in fact, creates a certain attribute of his own, which, as already mentioned, is not recommended.

What you should not do with data- * attributes


Such attributes should not contain content that should be accessible to assistive technologies. If some data should be visible on the page, or should be accessible to means for reading from the screen, it is not enough just to put it in the attribute data-*. Such data should also appear in regular HTML markup.

<!--      ,     -->
<div data-name="Chris Coyier"></div>

<!--      ,       ,    ... -->
<div>
  <span class="visually-hidden">Chris Coyier</span>
</div>

Here is material on how to hide web page elements.

Styling elements using data- * attributes


In CSS, you can select HTML elements based on attributes and their values.

/*      ,    */
[data-size="large"] {
  padding: 2rem;
  font-size: 125%;
}

/*    , ,  -  */
button[data-type="download"] { }
.card[data-pad="extra"] { }

This may seem interesting. For styling in HTML / CSS, classes are mainly used. And although classes are a wonderful tool (they differ in the average level of specificity, you can work with them using convenient JavaScript methods through the property of elements classList), an element can either have or not have a certain class (that is, the class in the element is either “included” , or “off”). When using attributes data-*, the developer also has the opportunity of classes (“on / off”) and the ability to select elements based on the value of the attribute that he has at the same level of specificity.

/*  ,      */
[data-size] { }

/*  ,      */
[data-state="open"],
[aria-expanded="true"] { }

/*  " ",      ,    "3",    -   ,   3 -  "3.14" */
[data-version^="3"] { }
/*  ""   ,      -    */
[data-company*="google"] { }

Specificity of attribute selectors


The specificity of attribute selectors is the same as for classes. Specificity is often considered as a 4-part value:

  • Inline style
  • ID
  • Classes and Attributes
  • Tags

As a result, if you imagine the value of specificity for an item that only stylized using an attribute selector, it will look like 0, 0, 1, 0

And here is another selector:

div.card[data-foo="bar"] { }

It will already be described by meaning 0, 0, 2, 1. The number 2appears here because there is both a class ( .card) and an attribute ([data-foo="bar"]). And 1here, due to the fact that there is only one tag ( div).

Here, to make it clearer, an illustrated version of these arguments.


1 tag, 1 class and 1 attribute

For attribute selectors, specificity is lower than for identifiers (ID), but higher than for tags (elements). Their specificity is equal to the specificity of classes.

Case insensitive attribute values


If you want selectors to select attributes whose values ​​may contain strings written using different combinations of lowercase and uppercase letters, you can use the case insensitive selector option.

/*     
<div data-state="open"></div>
<div data-state="Open"></div>
<div data-state="OPEN"></div>
<div data-state="oPeN"></div>
*/
[data-state="open" i] { }

This behavior ensures that a character is used in the selector i.

Display data stored in data- * attributes


CSS allows you to retrieve attribute values data-*and display them on the page.
 
/* <div data-emoji=":-)"> */

[data-emoji]::before {
  content: attr(data-emoji); /*  ':-)' */
  margin-right: 5px;
}

Examples of using data- * attributes to style elements


Attributes data-*can be used to indicate how many columns a gridcontainer should have . Here is the HTML code:

<div data-columns="2">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

<div data-columns="3">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

<div data-columns="4">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

Here is the relevant CSS:

[data-columns] {
  display: grid;
  grid-gap: 1rem;
  padding: 1rem;
  margin: 0 0 1rem 0;
}

[data-columns] > div {
  height: 100px;
  background: white;
}

[data-columns="2"] {
  background: #64B5F6;
  grid-template-columns: repeat(2, 1fr);
}

[data-columns="3"] {
  background: #9CCC65;
  grid-template-columns: repeat(3, 1fr);
}

[data-columns="4"] {
  background: #FFB74D;
  grid-template-columns: repeat(4, 1fr);
}

And here is a fragment of the resulting page.


Grid containers, which are configured using the data- * attributes. You can

experiment with this example on CodePen.

Working with data- * attributes in JavaScript


Attribute values data-*can be accessed, like the values ​​of other attributes, using the method getAtributefor reading data and the method setAttributefor writing.

//   
let value = el.getAttribute("data-state");

//   .

//  data-state   "collapsed"
el.setAttribute("data-state", "collapsed");

However, attributes data-*have their own special API. Suppose we have an element with several attributes data-*(which is completely normal):

<span 
  data-info="123" 
  data-index="2" 
  data-prefix="Dr. "
  data-emoji-icon=":-)"
></span>

If there is a link to this element, then you can read and write the values ​​of its attributes as follows:

// 
span.dataset.info; // 123
span.dataset.index; // 2

// 
span.dataset.prefix = "Mr. ";
span.dataset.emojiIcon = ";-)";

Note that the last line of the JS code uses the CamelCase style attribute name entry. The system automatically converts the names of the HTML attributes written in the kebab style to the names written in the camel style. That is - it data-this-little-piggyturns into dataThisLittlePiggy.

This the API, of course, is not as easy as the API classList , supporting clear methods such as add, remove, toggleand replace, but it's still better than nothing.

In JavaScript, you can work with data sets embedded in elements:

<img align="center" src="spaceship.png"
  data-ship-id="324" data-shields="72%"
  onclick="pewpew(this.dataset.shipId)">
</img>
<h2><font color="#3AC1EF">JSON-   data-*</font></h2>
<ul>
  <li data-person='
    {
      "name": "Chris Coyier",
      "job": "Web Person"
    }
  '></li>
</ul>

Why not write data-*JSON data to the attribute ? After all, these are just strings that can be formatted as valid JSON data (given quotation marks and more). If necessary, this data can be extracted from the attribute and parsed.

const el = document.querySelector("li");

let json = el.dataset.person;
let data = JSON.parse(json);

console.log(data.name); // Chris Coyier
console.log(data.job); // Web Person

About using data- * attributes in JavaScript


The idea here is to use attributes data-*to place data in HTML code that can be accessed from JavaScript to perform certain actions.

A common implementation of this scenario is aimed at organizing work with databases. Suppose we have a button Like:

<button data-id="435432343">Like</button>

This button may have a click handler that executes an AJAX request to the server. The handler, if the user likes something using the button, increases the number of likes in the server database. The handler knows which particular record needs to be updated, since it takes information about this from the attribute data-*.

Summary


Here , here and here are the standards associated with attribute selectors data-*. Here on the Caniuse website, you can learn about data-*browser support for attributes . If you have not used these attributes before, we hope this material has given you food for thought.

Dear readers! How do you use the data- * HTML attributes?


All Articles