If you need to attach custom attributes to an HTMLElement that you can also access from JavaScript or CSS,
please use data-attributes.
Let’s say you have a very simple gallery that has image thumbnails and it displays the full image
when you click on a thumbnail and also displays a caption for the image, we can define this gallery
in HTML as follows:
<div id="gallery">
<img
src="thumb1.jpg"
alt="Sunrise thumbnail"
class="thumbnail"
data-full-src="images/sunrise.jpg"
data-caption="Sunrise over the mountains"
>
<img
src="thumb2.jpg"
alt="City skyline thumbnail"
class="thumbnail"
data-full-src="images/skyline.jpg"
data-caption="Nighttime city skyline"
>
</div>
<div id="lightbox" class="hidden">
<button id="close-btn">❌</button>
<img id="lightbox-img" alt="">
<p id="lightbox-caption"></p>
</div>
Notice how for each image we used 2 attributes that start with data-:
data-full-src="..."
data-caption="..."
These allow us to hold the data related to the image in a semantic way, we can then access this data
via a uniform API from JavaScript:
const gallery = document.getElementById('gallery');
const lightbox = document.getElementById('lightbox');
const lbImg = document.getElementById('lightbox-img');
const lbCaption = document.getElementById('lightbox-caption');
const closeBtn = document.getElementById('close-btn');
gallery.addEventListener('click', e => {
const thumb = e.target.closest('.thumbnail');
if (!thumb) return;
const fullSrc = thumb.dataset.fullSrc;
const caption = thumb.dataset.caption;
lbImg.src = fullSrc;
lbImg.alt = thumb.alt;
lbCaption.textContent = caption;
lightbox.classList.remove('hidden');
});
closeBtn.addEventListener('click', () => {
lightbox.classList.add('hidden');
lbImg.src = '';
});
The important part to notice here is the use of the dataset read-only property on an element
...
const fullSrc = thumb.dataset.fullSrc;
const caption = thumb.dataset.caption;
...
you’ll also notice that, conveniently, we access these data attributes in camelCase.
Additionally, you can also access these attributes in CSS, let’s say you want to style the
thumbnails based on the data-caption, you could do something like this:
.thumbnail[data-caption*="night"] { border: 2px solid gold; }
<html>
<head>
<style>
.hidden { display: none; }
#lightbox {
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
background: rgba(0,0,0,0.8); text-align: center; padding-top: 50px;
}
#lightbox-img {
max-width: 80%;
max-height: 70%;
}
#lightbox-caption { color: white; margin-top: 10px; }
#close-btn {
position: absolute; top: 10px; right: 20px;
font-size: 2rem; color: white; background: none; border: none;
cursor: pointer;
}
</style>
</head>
<body>
<div id="gallery">
<img
src="thumb1.jpeg"
alt="Sunrise thumbnail"
class="thumbnail"
data-full-src="images/sunrise.jpg"
data-caption="Sunrise over the mountains"
>
<img
src="thumb2.jpeg"
alt="City skyline thumbnail"
class="thumbnail"
data-full-src="images/skyline.jpg"
data-caption="Nighttime city skyline"
>
</div>
<div id="lightbox" class="hidden">
<button id="close-btn">❌</button>
<img id="lightbox-img" alt="">
<p id="lightbox-caption"></p>
</div>
<script>
const gallery = document.getElementById('gallery');
const lightbox = document.getElementById('lightbox');
const lbImg = document.getElementById('lightbox-img');
const lbCaption = document.getElementById('lightbox-caption');
const closeBtn = document.getElementById('close-btn');
gallery.addEventListener('click', e => {
const thumb = e.target.closest('.thumbnail');
if (!thumb) return;
const fullSrc = thumb.dataset.fullSrc;
const caption = thumb.dataset.caption;
lbImg.src = fullSrc;
lbImg.alt = thumb.alt;
lbCaption.textContent = caption;
lightbox.classList.remove('hidden');
});
closeBtn.addEventListener('click', () => {
lightbox.classList.add('hidden');
lbImg.src = '';
});
</script>
</body>
</html>
https://developer.mozilla.org/en-US/docs/Web/HTML/How_to/Use_data_attributes
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset#in_html