In HTML, data-*
attributes are a way to store custom data on elements. These attributes don’t affect how the page looks or behaves directly, but they allow developers to store extra information in the HTML, such as user IDs, product types, language preferences, or access levels. This makes them ideal for use with JavaScript when you want to attach metadata to HTML elements.
The great thing about data-*
attributes is that you don’t need extra JavaScript files or hidden inputs to pass values. Everything is stored inline. There are two main ways to read these attributes in JavaScript:
- Using
element.dataset
— clean and modern, it automatically convertsdata-*
into camelCase properties. - Using
element.getAttribute("data-*")
— returns the raw attribute name and value exactly as written in HTML.
This article explores both methods with clear examples.
HTML Setup — Custom data-*
Attributes
We’ll begin with a basic div
that represents a developer profile. It includes three data-*
attributes: data-language
, data-level
, and data-user-name
. These values are not visible to the user, but we’ll access them using JavaScript.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Developer Card</title>
</head>
<body>
<div id="dev" data-language="Python" data-level="senior" data-user-name="Edward">
Developer Info
</div>
</body>
</html>
This div
will serve as the base for our upcoming examples.
Accessing with dataset
The dataset
property gives you a clean JavaScript object with each data-*
attribute as a property. It automatically removes the data-
prefix and converts hyphens to camelCase. Let’s look at a basic example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dataset Example</title>
</head>
<body>
<div id="dev" data-language="Python" data-level="senior" data-user-name="Edward">
Developer Info
</div>
<script>
const dev = document.getElementById('dev');
// Access using dataset
const language = dev.dataset.language; // Python
const level = dev.dataset.level; // senior
const userName = dev.dataset.userName; // Edward
console.log('Language:', language);
console.log('Level:', level);
console.log('User Name:', userName);
</script>
</body>
</html>
Here, you can see how data-user-name
becomes userName
when accessed using .dataset
. The hyphen is dropped, and the second part becomes capitalized — this is camelCase. The browser handles this automatically. It’s a clean and simple way to read custom data.
Accessing with getAttribute("data-*")
Now let’s do the same thing, but with getAttribute()
. This method reads the raw attribute from the HTML exactly as it appears, including the full data-
prefix.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>getAttribute Example</title>
</head>
<body>
<div id="dev" data-language="Python" data-level="senior" data-user-name="Edward">
Developer Info
</div>
<script>
const dev = document.getElementById('dev');
// Access using getAttribute
const language = dev.getAttribute('data-language'); // Python
const level = dev.getAttribute('data-level'); // senior
const userName = dev.getAttribute('data-user-name'); // Edward
console.log('Language:', language);
console.log('Level:', level);
console.log('User Name:', userName);
</script>
</body>
</html>
Unlike .dataset
, this method uses the attribute name exactly as defined in HTML. This means you need to remember the dashes (-
) and the full prefix.
Comparison Table
Let’s compare the two methods:
Method | How to Use | Notes |
---|---|---|
element.dataset | element.dataset.userName | Auto converts to camelCase |
getAttribute() | element.getAttribute("data-user-name") | Uses exact attribute name from HTML |
Use .dataset
for cleaner, camelCase-friendly access. Use getAttribute()
when you need exact names or are processing dynamic attributes.
Fun Interactive Example
Let’s build a small interactive example. Clicking on a character’s name will show an alert with their favorite programming language, which is stored using a data-language
attribute.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Character Click</title>
<style>
.character {
cursor: pointer;
margin: 10px;
font-size: 1.2rem;
}
</style>
</head>
<body>
<div class="character" data-language="Python">Edward</div>
<div class="character" data-language="JavaScript">Lucia</div>
<div class="character" data-language="Ruby">Cherish</div>
<script>
const characters = document.querySelectorAll('.character');
characters.forEach(character => {
character.addEventListener('click', () => {
const name = character.textContent;
const language = character.dataset.language;
alert(`${name}'s favorite language is ${language}`);
});
});
</script>
</body>
</html>
Each div.character
has a data-language
attribute. When clicked, JavaScript uses dataset.language
to get the value and shows it in an alert. This is a real-world way to create clean interactions without extra markup or external config.
Conclusion
Now you’ve seen how to access HTML data-*
attributes using two clear and simple methods. The dataset
approach turns your attributes into an easy-to-use object with camelCase keys, while getAttribute()
gives you full control over exact attribute names.
Use dataset
when you want fast, readable code. Use getAttribute()
when you need precise control or are working with attributes that don’t follow camelCase rules.
References
- MDN: Using data attributes
A detailed guide on how to use customdata-*
attributes in HTML for storing extra information. - MDN: HTMLElement.dataset
Official documentation explaining thedataset
property for accessing data attributes as a JavaScript object. - MDN: Element.getAttribute()
Reference for thegetAttribute()
method used to retrieve the exact value of any HTML attribute, includingdata-*
attributes.