Briefly
The dataset
property allows you to read or set any data attributes on the HTML element.
A data attribute is a custom attribute on an element, the name of which begins with data
, for example, data
. Data attributes are used to store values on elements in HTML.
How it is written
Accessing the dataset
property will return an object with all the data attributes present on the element. The field names in the object will be the names of the data attributes after the data
prefix. For example, if the attribute is named data
, then the field in the object for this attribute will be named columns
.
<h1>Famous Sith</h1><ul> <li data-id="1541" data-episode="1">Darth Maul</li> <li data-id="9434" data-episode="4">Darth Vader</li> <li data-id="5549" data-episode="4">Darth Sidious</li></ul>
<h1>Famous Sith</h1> <ul> <li data-id="1541" data-episode="1">Darth Maul</li> <li data-id="9434" data-episode="4">Darth Vader</li> <li data-id="5549" data-episode="4">Darth Sidious</li> </ul>
const items = document.querySelectorAll('li')const firstItem = items[0]console.log(firstItem.dataset)// { id: '1541', episode: '1' }
const items = document.querySelectorAll('li') const firstItem = items[0] console.log(firstItem.dataset) // { id: '1541', episode: '1' }
If there are no data attributes on the element, an empty object will be returned:
const heading = document.querySelector('h1')console.log(heading.dataset)// {}
const heading = document.querySelector('h1') console.log(heading.dataset) // {}
To add a data attribute to an element, you need to add a new field to the dataset
object. The field name should also be without the data
prefix; the browser will automatically add it. The values of the attributes in HTML can only be strings, so any value will be automatically converted to a string.
Let's take the same HTML from the example above and add data attributes to the second element:
const items = document.querySelectorAll('li')const secondItem = items[1]secondItem.dataset.side = 'evil'secondItem.dataset.age = 46secondItem.dataset.lightsaber = { color: 'red' }
const items = document.querySelectorAll('li') const secondItem = items[1] secondItem.dataset.side = 'evil' secondItem.dataset.age = 46 secondItem.dataset.lightsaber = { color: 'red' }
As a result, we get the following element:
<li data-id="9434" data-episode="4" data-side="evil" data-age="46" data-lightsaber="[object Object]"> Darth Vader</li>
<li data-id="9434" data-episode="4" data-side="evil" data-age="46" data-lightsaber="[object Object]"> Darth Vader </li>
All non-string values set in dataset
will be converted to a string. Therefore, the object turns into [object
, and the number 46 becomes the string "46"
.
If a field with an empty value is added to dataset
, a data attribute without a value will be created in HTML.
Using camelCase and kebab-case
In dataset
, you must assign fields with names written as a single word. Therefore, for compound names, only camel
notation is used. Attempting to assign a name in kebab
will throw an error.
const body = document.querySelector('body')body.dataset['dark-theme'] = true// Uncaught DOMException: Failed to set// a named property on 'DOMStringMap':// 'dark-theme' is not a valid property name
const body = document.querySelector('body') body.dataset['dark-theme'] = true // Uncaught DOMException: Failed to set // a named property on 'DOMStringMap': // 'dark-theme' is not a valid property name
Data attributes written in dataset
using camel
will have names in kebab
in HTML. The browser converts camel
to kebab
:
<ul> <li>Ivan Ivanov</li></ul>
<ul> <li>Ivan Ivanov</li> </ul>
const item = document.querySelector('li')item.dataset.yearsOfExperience = 2item.dataset.candidateRole = 'junior'
const item = document.querySelector('li') item.dataset.yearsOfExperience = 2 item.dataset.candidateRole = 'junior'
After executing the above code, the following HTML will result:
<ul> <li data-candidate-role="junior" data-years-of-experience="2"> Ivan Ivanov </li></ul>
<ul> <li data-candidate-role="junior" data-years-of-experience="2"> Ivan Ivanov </li> </ul>
The name transformation also works in reverse — a data attribute on an HTML element written in kebab
will be transformed into camel
in dataset
.
<ul> <li data-candidate-role="junior">Ivan Ivanov</li></ul>
<ul> <li data-candidate-role="junior">Ivan Ivanov</li> </ul>
const item = document.querySelector('li')console.log(item.dataset)// { candidateRole: 'junior' }
const item = document.querySelector('li') console.log(item.dataset) // { candidateRole: 'junior' }
Removing a data attribute
You can only remove a data attribute using the delete
operator. If you try to assign a value of undefined
or null
to a field, the browser will simply assign the string 'undefined'
or 'null'
to the attribute.
Let's take the following HTML:
<div data-testid="test">Any content<div>
<div data-testid="test">Any content<div>
When setting undefined
as the value of a data attribute, it will not be removed from the element.
const element = document.querySelector('div')element.dataset.testid = undefined
const element = document.querySelector('div') element.dataset.testid = undefined
As a result, the following HTML will result:
<div data-testid="undefined">Any content<div>
<div data-testid="undefined">Any content<div>
If you use the delete
operator, you will get an element without the data attribute.
delete element.dataset.testid
delete element.dataset.testid
<div>Any content</div>
<div>Any content</div>
The dataset
property is protected from overwriting. This means that attempting to assign a new value to dataset
will be ignored.
const element = document.querySelector('div')// Nothing will happen, data attributes// on the elements will also not changeelement.dataset = {}element.dataset = 'string'
const element = document.querySelector('div') // Nothing will happen, data attributes // on the elements will also not change element.dataset = {} element.dataset = 'string'
How to Understand
Data attributes appeared in HTML5 and added the ability for developers to add their own attributes to elements. There can be many reasons to use such attributes. Most often, data attributes store necessary values that are used in CSS or JavaScript.
Data attributes were specifically created to store and work with data directly in HTML. Hence the prefix data, which translates to data. For example, with data attributes, you can store a value selected in a dropdown list directly on the element.
Storing data on HTML elements is also useful for initializing widgets in JavaScript. They can find the necessary elements using the data attribute as a selector and read the data from the attribute. For example, in multi-page applications, HTML is generated on the server, and the ready page is sent in response to a request. During generation, data attributes can be injected with server data into HTML, thus passing them to JavaScript.
In theory, a regular identifier id
could also be used for the same purpose, but the intent of this attribute is quite different. Furthermore, the specification requires the value of the id
attribute to be unique across the entire page.
There can be any number of data attributes on an element, making it convenient to place separate pieces of data in their attributes. This is something that cannot be achieved using only an identifier.
The browser provides an opportunity to manage data attributes through the special dataset
API.
In practice
Advice 1
🛠 The data attribute can be used to apply styles. Elements can be selected CSS selector by attribute:
[data-id] { /* Selector for all elements with data-id */}[data-id="123"] { /* Selector only for elements with data-id="123" */}
[data-id] { /* Selector for all elements with data-id */ } [data-id="123"] { /* Selector only for elements with data-id="123" */ }
Find the element with data
:
const element = document.querySelector('[data-id="123"]')
const element = document.querySelector('[data-id="123"]')
🛠 Some frameworks automatically generate data attributes during compilation and assign them to elements to isolate CSS.
🛠 Data attributes are widely used in automated testing. For this, data attributes are placed on the necessary elements, and the test refers to them. In the documentation for various testing libraries, you can often find the attribute data
.