Atributos data-*: el puente entre HTML y JavaScript
Los atributos data-* permiten almacenar información personalizada directamente en los elementos HTML. Son el canal oficial entre el marcado y JavaScript: limpios, semánticos y sin necesidad de variables globales ni clases CSS con significado oculto.
Sintaxis básica
Cualquier atributo que empiece por data- seguido de al menos un carácter es un atributo de datos válido:
<article
data-id="42"
data-categoria="frontend"
data-publicado="2026-03-20"
data-destacado="true"
>
<h2>HTML Intermedio</h2>
</article>
Reglas de nomenclatura
- Solo letras minúsculas, números y guiones. Sin mayúsculas.
- No pueden empezar por
xml. - No pueden contener dos puntos (
:).
<!-- ✅ Correcto -->
<div data-user-id="1" data-max-items="10">...</div>
<!-- ❌ Incorrecto -->
<div data-userId="1" data-Max-items="10">...</div>
Acceder a data-* desde JavaScript
La propiedad dataset del elemento expone todos sus atributos data-* como un objeto. Los guiones del nombre se convierten en camelCase automáticamente:
<article
id="post-1"
data-id="42"
data-categoria="frontend"
data-publicado="2026-03-20"
>
Artículo
</article>
<script>
const articulo = document.getElementById('post-1');
// Leer
console.log(articulo.dataset.id); // "42"
console.log(articulo.dataset.categoria); // "frontend"
console.log(articulo.dataset.publicado); // "2026-03-20"
// Escribir (modifica el atributo en el DOM)
articulo.dataset.categoria = 'css';
// Borrar
delete articulo.dataset.publicado;
// Comprobar si existe
console.log('id' in articulo.dataset); // true
</script>
Conversión de nombres: guión → camelCase
| Atributo HTML | dataset en JS |
|---|---|
data-id | dataset.id |
data-user-name | dataset.userName |
data-max-items | dataset.maxItems |
data-is-active | dataset.isActive |
Caso práctico: lista de ítems filtrables
<div>
<button data-filtro="todos">Todos</button>
<button data-filtro="frontend">Frontend</button>
<button data-filtro="backend">Backend</button>
</div>
<ul id="lista">
<li data-categoria="frontend">HTML semántico</li>
<li data-categoria="backend">Node.js y APIs</li>
<li data-categoria="frontend">CSS Grid avanzado</li>
<li data-categoria="backend">Bases de datos SQL</li>
</ul>
<script>
const items = document.querySelectorAll('#lista li');
const botones = document.querySelectorAll('[data-filtro]');
botones.forEach((btn) => {
btn.addEventListener('click', () => {
const filtro = btn.dataset.filtro;
items.forEach((item) => {
const visible = filtro === 'todos' || item.dataset.categoria === filtro;
item.hidden = !visible;
});
});
});
</script>
Caso práctico: componente de tabs
<nav>
<button data-tab="html" class="activo">HTML</button>
<button data-tab="css">CSS</button>
<button data-tab="js">JavaScript</button>
</nav>
<section data-panel="html">
<p>Contenido de HTML.</p>
</section>
<section data-panel="css" hidden>
<p>Contenido de CSS.</p>
</section>
<section data-panel="js" hidden>
<p>Contenido de JavaScript.</p>
</section>
<script>
const tabs = document.querySelectorAll('[data-tab]');
const panels = document.querySelectorAll('[data-panel]');
tabs.forEach((tab) => {
tab.addEventListener('click', () => {
const target = tab.dataset.tab;
tabs.forEach((t) => t.classList.remove('activo'));
tab.classList.add('activo');
panels.forEach((panel) => {
panel.hidden = panel.dataset.panel !== target;
});
});
});
</script>
Usar data-* desde CSS
Los atributos data-* son accesibles desde CSS con el selector de atributos. Esto permite cambiar estilos basados en datos sin añadir clases:
<span data-estado="activo">Usuario</span>
<span data-estado="inactivo">Otro usuario</span>
[data-estado="activo"] {
color: #22c55e;
}
[data-estado="inactivo"] {
color: #ef4444;
}
También puedes mostrar el valor del atributo con attr() en la propiedad content:
/* Muestra el nombre del atajo de teclado junto al elemento */
[data-atajo]::after {
content: ' (' attr(data-atajo) ')';
font-size: 0.75em;
opacity: 0.6;
}
<button data-atajo="Ctrl+S">Guardar</button>
<!-- Se renderiza como: "Guardar (Ctrl+S)" -->
Pasar configuración a componentes
Un patrón muy útil es usar data-* para configurar componentes JavaScript sin código extra:
<!-- Carrusel autoplay cada 3 segundos -->
<div
class="carrusel"
data-autoplay="true"
data-intervalo="3000"
data-loop="true"
>
<img src="slide-1.jpg" alt="Slide 1" />
<img src="slide-2.jpg" alt="Slide 2" />
</div>
<script>
document.querySelectorAll('.carrusel').forEach((el) => {
const { autoplay, intervalo, loop } = el.dataset;
iniciarCarrusel(el, {
autoplay: autoplay === 'true',
intervalo: Number(intervalo),
loop: loop === 'true',
});
});
</script>
Este patrón permite tener múltiples instancias con configuraciones distintas sin JavaScript adicional.
Alternativa a getAttribute
Hay dos formas de leer atributos data-*. dataset es la más moderna y recomendada:
const el = document.querySelector('[data-id]');
// Forma antigua
el.getAttribute('data-id'); // "42"
el.setAttribute('data-id', '99');
// Forma moderna (recomendada)
el.dataset.id; // "42"
el.dataset.id = '99';
¿Qué hemos aprendido?
- Los atributos
data-*almacenan datos personalizados en los elementos HTML. datasetlos expone en JavaScript con nombres en camelCase.- Se pueden leer, escribir y borrar directamente desde
dataset. - Son accesibles desde CSS con selectores de atributo.
- Son ideales para configurar componentes y filtrar listas sin variables extra.
Siguiente paso
En la próxima lección veremos atributos HTML que deberías conocer: defer, async, rel, hidden, inert, contenteditable, tabindex y más.