Tagi HTML: data

6 min. czytania

Atrybuty data-* to potężne narzędzie w arsenale każdego programisty HTML, umożliwiające przechowywanie niestandardowych danych bezpośrednio w elementach strony. Pozwalają one na przekazywanie informacji do JavaScriptu i CSS bez zaśmiecania kodu dodatkowymi klasami czy identyfikatorami (ID), dzięki czemu kod pozostaje czytelny i elastyczny.

Czym dokładnie są atrybuty data-*?

Atrybuty data-* zostały wprowadzone w HTML5 jako standardowy sposób na osadzanie prywatnych danych w elementach HTML. Ich składnia jest prosta: zawsze zaczynają się od data-, po myślniku następuje nazwa atrybutu (w małych literach, z myślnikami zamiast spacji), a wartość umieszczamy w cudzysłowach. Na przykład:

<div data-user-id="12345" data-user-role="admin">Profil użytkownika</div>

Tutaj data-user-id przechowuje identyfikator użytkownika (12345), a data-user-role rolę (admin). Te dane nie wpływają na wygląd elementu, ale są dostępne dla skryptów i stylów.

Dlaczego nie używać zwykłych atrybutów jak id czy class? Atrybuty data-* są dedykowane do prywatnych metadanych – nie służą do stylizacji (jak klasy) ani unikalnej identyfikacji (jak ID). Są wspierane przez przeglądarki i nie powodują błędów w walidatorach HTML, w przeciwieństwie do niestandardowych atrybutów.

Główne zastosowania atrybutów data-*

Atrybuty data-* znajdują szerokie zastosowanie w nowoczesnym frontendzie. Oto najważniejsze scenariusze:

  • przechowywanie identyfikatorów i nazw – idealne do linkowania elementów z bazą danych, np. ID produktu w e-sklepie;
  • przekazywanie ustawień do skryptów – slajder z prędkością animacji czy autoodtwarzaniem;
  • metadane dla UX – status zadań w liście to-do;
  • informacje dla CSS/JS – warunkowe style bez dodatkowych klas.

Przykładowy slajder z ustawieniami, które JS może odczytać i zastosować:

<div class="slider" data-speed="3000" data-autoplay="true">
<img src="slide1.jpg" alt="Pierwszy slajd">
<img src="slide2.jpg" alt="Drugi slajd">
</div>

Lista zadań z przypisanymi statusami do warunkowego stylowania i logiki:

<ul>
<li data-status="done">Zadanie ukończone</li>
<li data-status="in-progress">W trakcie</li>
<li data-status="pending">Oczekujące</li>
</ul>

Dzięki temu możesz dynamicznie zmieniać zachowanie interfejsu bez przebudowy HTML.

Odczytywanie data-* w CSS – warunkowe stylizowanie

Jedna z największych zalet data-* to integracja z CSS. Używając selektorów atrybutowych, możesz stylizować elementy na podstawie wartości atrybutów data-*. To pozwala tworzyć responsywne i czytelne interfejsy bez dodatkowych klas.

Przykład stylizacji listy zadań na podstawie statusu:

[data-status="done"] { color: green; text-decoration: line-through; }
[data-status="in-progress"] { color: orange; font-weight: bold; }
[data-status="pending"] { color: red; opacity: 0.7; }

Efekt? Elementy automatycznie zmieniają wygląd w zależności od data-status, na przykład:

  • zielony i przekreślony dla „done”,
  • pomarańczowy i pogrubiony dla „in-progress”,
  • czerwony z lekką przezroczystością dla „pending”.

Teoretycznie można też odwoływać się do wartości atrybutu bezpośrednio w deklaracjach CSS, ale to rozwiązanie ma ograniczone wsparcie przeglądarek. Przykład (eksperymentalny):

[data-autoplay="true"] {
/* Uwaga: attr() w wartościach właściwości jest słabo wspierane – w praktyce użyj JS */
animation-duration: attr(data-speed ms);
}

W praktyce parametry wpływające na zachowanie (np. prędkość) lepiej odczytać w JS i zastosować w stylach programowo.

Odczytywanie i manipulacja data-* w JavaScript

W JavaScript dostęp do data-* jest banalny dzięki obiektowi dataset. Dla atrybutu data-user-id używasz element.dataset.userId (nazwa w atrybucie jest kebab-case, a w JS konwertowana do camelCase).

Przykład przycisku z danymi użytkownika w HTML:

<button id="myBtn" data-user-id="123" data-role="admin">Kliknij mnie!</button>

A tak odczytasz i zmienisz wartości w JavaScript:

const btn = document.getElementById('myBtn');
console.log(btn.dataset.userId); // "123"
console.log(btn.dataset.role); // "admin"

// Zmiana wartości:
btn.dataset.status = 'clicked';
console.log(btn.getAttribute('data-status')); // "clicked"

Teraz pełny przykład interaktywnej listy zadań z obsługą zmiany statusu:

<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>Lista zadań z data-*</title>
<style>
[data-status="done"] { color: green; text-decoration: line-through; }
[data-status="in-progress"] { color: orange; font-weight: bold; }
[data-status="pending"] { color: red; }
</style>
</head>
<body>
<ul id="todo-list">
<li data-status="pending">Nauczyć się data-* <button class="toggle">Przełącz</button></li>
<li data-status="in-progress">Zbudować aplikację <button class="toggle">Przełącz</button></li>
</ul>

<script>
document.querySelectorAll('.toggle').forEach(btn => {
btn.addEventListener('click', () => {
const li = btn.closest('li');
const currentStatus = li.dataset.status;
li.dataset.status = currentStatus === 'done'
? 'pending'
: (currentStatus === 'in-progress' ? 'done' : 'in-progress');
});
});
</script>
</body>
</html>

Kliknięcie przycisku cyklicznie zmienia status (pending → in-progress → done → pending), a CSS automatycznie aktualizuje wygląd elementu.

Zaawansowane triki z data-*

1. Data-* w formularzach

Przechowuj reguły walidacji po stronie klienta i wyświetlaj własny komunikat błędu:

<input type="email" data-required="true" data-error-msg="Podaj poprawny email">

Przykładowa obsługa w JS:

if (input.dataset.required === 'true' && !input.value) {
input.setCustomValidity(input.dataset.errorMsg);
} else {
input.setCustomValidity('');
}

2. Data-* z JSON dla złożonych obiektów

Wartości mogą być ciągami znaków JSON zakodowanymi w atrybucie:

<div id="config" data-settings='{"theme": "dark", "lang": "pl"}'></div>

A tak je odczytasz i sparsujesz w JS:

const configEl = document.getElementById('config');
const config = JSON.parse(configEl.dataset.settings);
console.log(config.theme); // "dark"

3. Integracja z frameworkami

W React/Vue/Angular atrybuty data-* działają natywnie i możesz je przekazywać jak zwykłe propsy/atrybuty. Przykład w React:

<div data-id={user.id}>{user.name}</div>

4. Bezpieczeństwo i dobre praktyki

Trzymaj się poniższych zasad, aby uniknąć problemów i utrzymać spójność kodu:

  • używaj małych liter i myślników w nazwach atrybutów,
  • nie przechowuj wrażliwych danych (zastosuj mechanizmy po stronie serwera),
  • waliduj i sanityzuj dane w JS przed użyciem,
  • w złożonych interfejsach rozważ mikrobiblioteki (np. Alpine.js), które naturalnie wykorzystują data-*.

Porównanie data-* z alternatywami

Oto zestawienie popularnych podejść do przekazywania metadanych w interfejsie:

Podejście Zalety Wady
data-* Standardowe, dostępne w CSS/JS Tylko ciągi znaków (czasem konieczne parsowanie JSON)
Klasy CSS Łatwe i szybkie stylizowanie Zaśmiecanie kodu, brak przechowywania wartości liczbowych
Właściwości niestandardowe (zmienne CSS) Dynamiczne style i dziedziczenie Tylko do stylów, nie nadają się jako źródło danych w JS
ID + mapa w JS Unikalność i kontrola po stronie skryptu Mniej elastyczne, trudniejsze w skalowaniu i utrzymaniu

Atrybuty data-* często wygrywają dzięki uniwersalności: są proste, czytelne i działają jednocześnie w HTML, CSS i JS.

Masz pytania? Podziel się w komentarzach swoim przykładem użycia data-*!