• Sobre mí
  • Proyectos
  • Contacto
  • Blog

Apasionado por el desarrollo web y el diseño de interfaces intuitivas.

Cada error es un paso. Cada línea, un aprendizaje.

📍   Salou, Tarragona, España ✉️   [email protected] 📞   +34 641932611

Curriculum

Ver mi curriculum completo

Mapa del sitio

  • Inicio
  • Blog
  • Proyectos
  • Sobre mi
  • Mi misión
  • Sitemap

Contácto

  • Página de contácto
  • LinkedIn
  • GitHub

2026 Frankuxui - Todos los derechos reservados

  • Términos y condiciones
  • Política de privacidad
  • Política de cookies
Fotografía de unsplash creada por Carter Obasohan
Fotografía de unsplash creada por Carter Obasohan
  • HTML
  • JavaScript

Articulo publicado el 8 de julio de 2026

Por Frank Esteban Isdray Junco

Atributos data-* en HTML: Almacena datos personalizados en tu DOM

Aprende a usar los atributos data-* para guardar información en elementos HTML y accederla desde JavaScript de forma segura y semántica

Por qué necesitas comprender los atributos data-*

Cuando trabajas con JavaScript interactivo, con frecuencia necesitas asociar información adicional a elementos del DOM. Quizás necesitas almacenar un ID de producto en un botón de compra, el estado abierto o cerrado de un accordion, o configuraciones personalizadas para un componente.

Antes de que existieran los atributos data-*, los desarrolladores usaban soluciones improvisadas: clases CSS con información codificada, variables globales, o peor aún, modificaban propiedades directas de los elementos del DOM. Todo eso era frágil, poco semántico y difícil de mantener.

Los atributos data-* solucionan este problema de forma estándar. Son atributos HTML personalizados que te permiten guardar datos arbitrarios en cualquier elemento, accesibles desde JavaScript sin modificar el árbol del DOM ni la semántica del elemento.

Los atributos data-* son un mecanismo oficial del estándar HTML5 para incrustar datos personalizados en elementos. Están disponibles en todos los navegadores modernos y son una mejor práctica recomendada por WHATWG (Web Hypertext Application Technology Working Group).

Sintaxis y nomenclatura

La sintaxis es sencilla: cualquier atributo que comience con data- seguido de un nombre en minúsculas (con guiones opcionales) es un atributo de datos válido.

html
<!-- Ejemplos válidos -->
<button data-id="123">Comprar</button>
<div data-status="active">Activo</div>
<article data-published-date="2026-07-07">...</article>
<section data-config-timeout="5000" data-config-retry="3">...</section>

Reglas de nomenclatura

La especificación tiene pocas restricciones, pero las convenciones ayudan a mantener el código legible:

  • Comienza siempre con data-.
  • Usa solo letras minúsculas, números y guiones.
  • Evita nombres genéricos como data-value si puedes ser específico: usa data-product-id en su lugar.
  • Usa guiones para separar conceptos: data-accordion-multiple, data-modal-trigger.
html
<!-- Mal: demasiado genérico -->
<div data-value="open"></div>

<!-- Bien: específico y descriptivo -->
<div data-accordion-state="open"></div>

Accediendo a los datos desde JavaScript

Una vez que has almacenado datos en atributos data-*, necesitas recuperarlos. JavaScript ofrece dos formas principales: el atributo dataset (recomendado) y getAttribute().

Usando dataset (recomendado)

La propiedad dataset convierte automáticamente los atributos data-* en propiedades JavaScript accesibles. Los guiones se transforman en camelCase.

html
<button id="btn" data-user-id="42" data-action="submit">Enviar</button>
javascript
const btn = document.getElementById("btn");

// Acceso mediante dataset (camelCase)
console.log(btn.dataset.userId); // "42"
console.log(btn.dataset.action); // "submit"

// Modificar datos
btn.dataset.status = "loading"; // Añade data-status="loading"

// Eliminar datos
delete btn.dataset.userId; // Remueve el atributo data-user-id

Ventajas de dataset:

  • Sintaxis limpia y legible.
  • Conversión automática de camelCase.
  • Interfaz estándar.

Usando getAttribute()

Para casos donde necesites controlar exactamente el nombre del atributo, getAttribute() sigue siendo útil:

javascript
const btn = document.getElementById("btn");

// Acceso directo al atributo completo
console.log(btn.getAttribute("data-user-id")); // "42"

// Modificar
btn.setAttribute("data-status", "loading");

// Eliminar
btn.removeAttribute("data-user-id");

Casos de uso reales

Los atributos data-* brillan cuando necesitas asociar datos a elementos HTML sin crear propiedades en JavaScript o modificar el árbol del DOM.

Configuración de componentes interactivos

Muchos componentes reutilizables necesitan opciones personalizables. Los atributos data-* permiten expresar esa configuración directamente en HTML:

Expresar opciones en HTML

La clave es que el componente JavaScript pueda detectar automáticamente esos atributos y usarlos para su inicialización:

html
<!-- Accordion configurado por atributos data-* -->
<section id="faq" data-accordion data-accordion-multiple="false" data-accordion-open="0">
  <article data-accordion-item>
    <h3>
      <button type="button" data-accordion-trigger>¿Qué es esto?</button>
    </h3>
    <div data-accordion-panel>
      <p>Contenido...</p>
    </div>
  </article>
</section>

El JavaScript puede detectar automáticamente estos atributos y configurar el componente sin necesidad de pasar opciones adicionales:

javascript
class Accordion {
  constructor(rootElement) {
    this.root = rootElement;
    this.multiple = this.root.dataset.accordionMultiple === "true";
    this.initialOpen = parseInt(this.root.dataset.accordionOpen, 10) || null;
    this.init();
  }

  init() {
    // Usar this.multiple y this.initialOpen
  }
}

// Inicializar automáticamente todos los accordions
document.querySelectorAll("[data-accordion]").forEach((el) => {
  new Accordion(el);
});

Almacenar identificadores únicos

Cuando necesitas vincular elementos del DOM con datos en tu aplicación (IDs de base de datos, SKUs de productos, etc.), los atributos data-* son el lugar natural:

html
<li data-product-id="1024">
  <h4>Laptop Pro</h4>
  <p data-price="1299.99">$1,299.99</p>
  <button data-action="add-to-cart">Añadir al carrito</button>
</li>
javascript
document.querySelectorAll("[data-action='add-to-cart']").forEach((btn) => {
  btn.addEventListener("click", (e) => {
    const li = e.target.closest("li");
    const productId = li.dataset.productId;
    const price = li.querySelector("[data-price]").dataset.price;

    console.log(`Añadiendo producto ${productId} a $${price}`);
    addToCart(productId, price);
  });
});

Gestionar estado de elementos

Para estados visuales o de lógica que cambien dinámicamente, los atributos data-* son perfectos porque el estado vive en el DOM, donde pertenece:

html
<div id="modal" data-state="closed">
  <h2>Diálogo</h2>
  <button data-action="close">Cerrar</button>
</div>
javascript
const modal = document.getElementById("modal");

function openModal() {
  modal.dataset.state = "open";
}

function closeModal() {
  modal.dataset.state = "closed";
}

// CSS reactivo al estado
// [data-state="open"] { display: block; }
// [data-state="closed"] { display: none; }

Vinculación de eventos a datos

En interfaces con muchos elementos similares (listas de items, tablas), los atributos data-* eliminan la necesidad de listeners duplicados gracias a event delegation:

html
<table>
  <tbody>
    <tr data-row-id="101">
      <td>Producto A</td>
      <td><button data-action="edit">Editar</button></td>
    </tr>
    <tr data-row-id="102">
      <td>Producto B</td>
      <td><button data-action="edit">Editar</button></td>
    </tr>
  </tbody>
</table>
javascript
document.querySelector("table").addEventListener("click", (e) => {
  if (e.target.dataset.action === "edit") {
    const rowId = e.target.closest("tr").dataset.rowId;
    editRow(rowId);
  }
});

Un único listener maneja todos los botones, accediendo a datos específicos de cada fila sin necesidad de closures o listeners individuales.

Seguridad y consideraciones

Nunca almacenes información sensible

Los atributos data-* son visibles en el HTML origen. Cualquiera puede inspeccionar la página y verlos. Nunca guardes:

javascript
// ❌ NUNCA: tokens, contraseñas o datos sensibles
<div data-api-token="sk_live_abcd1234..."></div>
<button data-user-password="micontraseña123"></button>

// ✅ SI: identificadores públicos o configuración no sensible
<div data-user-id="42"></div>
<button data-action="delete" data-item-id="99"></button>

Valida y sanitiza los datos

Los atributos data-* son texto sin procesar. Si usas los datos de forma dinámica (como selectores CSS, URLs o código), debes validar y sanitizar:

html
<div data-redirect-url="https://example.com/page">Click aquí</div>
javascript
// ❌ Inseguro: inyección potencial
element.addEventListener("click", () => {
  window.location = element.dataset.redirectUrl;
});

// ✅ Seguro: valida la URL
element.addEventListener("click", () => {
  const url = new URL(element.dataset.redirectUrl, window.location.origin);
  if (url.origin === window.location.origin) {
    window.location = url.href;
  }
});

Rendimiento y buenas prácticas

Usa dataset para legibilidad

La propiedad dataset es más legible que getAttribute(). Aunque ambas tienen rendimiento similar, el código es la principal consideración:

Comparativa de sintaxis

A continuación, una comparación clara entre ambas aproximaciones:

javascript
// Legible
element.dataset.productId;

// Menos legible
element.getAttribute("data-product-id");

Prefiere CSS y selectores sobre inspeccionar atributos

Cuando sea posible, usa CSS para reaccionar a atributos data-* en lugar de inspeccionar el DOM desde JavaScript:

css
/* Mejor: CSS maneja la presentación */
[data-state="loading"] {
  pointer-events: none;
  opacity: 0.6;
}
javascript
// En lugar de inspeccionar el estado desde JS cada vez
element.dataset.state = "loading";
// No necesitas hacer element.classList.add("loading") o similar

Agrupa datos relacionados con convenciones

Cuando un elemento tenga múltiples datos relacionados, usa un prefijo común para claridad:

html
<!-- Datos agrupados lógicamente -->
<div data-modal-id="form" data-modal-size="lg" data-modal-dismissible="true">
  <!-- Mejor que: data-id, data-size, data-dismissible -->
</div>

Mantén los datos simples

Los atributos data-* almacenan texto. Si necesitas estructuras complejas, considera usar data- JSON:

html
<!-- ❌ Difícil de mantener -->
<div data-config-a="1" data-config-b="2" data-config-c="3"></div>

<!-- ✅ Más claro: JSON válido en un único atributo -->
<div data-config='{"timeout": 5000, "retry": 3, "debug": true}'></div>
javascript
const config = JSON.parse(element.dataset.config);
console.log(config.timeout); // 5000

Casos donde NO usar data-*

No todo problema requiere atributos data-*. Considera alternativas en estos casos:

  1. Datos que cambian frecuentemente: Si un valor se actualiza constantemente (posición del ratón, scroll, frame count), no lo almacenes en atributos; usa variables en JavaScript.

  2. Lógica compleja: Si el dato requiere transformaciones o cálculos, mantenlo en estado de JavaScript, no en HTML.

  3. Datos privados de componentes: Si un componente necesita estado interno que la interfaz HTML no debe exponer, usa propiedades de la clase o WeakMaps.

javascript
// ❌ Evitar: estado frágil y expuesto
element.dataset.internalCounter = "0";

// ✅ Mejor: estado privado
class Component {
  #counter = 0;

  increment() {
    this.#counter++;
  }
}

Conclusión

Los atributos data-* son un estándar elegante y eficaz para vincular datos a elementos HTML. Son especialmente útiles en componentes reutilizables, manejo de eventos delegados y expresar configuración en HTML de forma legible. Úsalos como puente entre el marcado HTML y la lógica JavaScript, pero recuerda: no son un almacenamiento permanente, no son seguros para datos sensibles, y no reemplazan el estado adecuado de JavaScript cuando la lógica lo requiere. Combinados con CSS, selectores y listeners delegados, los atributos data-* crean interfaces más robustas, mantenibles y semánticas.

En este artículo

  1. Por qué necesitas comprender los atributos data-*
  2. Sintaxis y nomenclatura
  3. Reglas de nomenclatura
  4. Accediendo a los datos desde JavaScript
  5. Usando dataset (recomendado)
  6. Usando getAttribute()
  7. Casos de uso reales
  8. Configuración de componentes interactivos
  9. Expresar opciones en HTML
  10. Almacenar identificadores únicos
  11. Gestionar estado de elementos
  12. Vinculación de eventos a datos
  13. Seguridad y consideraciones
  14. Nunca almacenes información sensible
  15. Valida y sanitiza los datos
  16. Rendimiento y buenas prácticas
  17. Usa dataset para legibilidad
  18. Prefiere CSS y selectores sobre inspeccionar atributos
  19. Agrupa datos relacionados con convenciones
  20. Mantén los datos simples
  21. Casos donde NO usar data-*
  22. Conclusión

Articulos relacionados

Estos articulos pueden interesarte si te gusto este articulo.

Imagen de Unsplash creada por Marek Piwnicki
Imagen del articulo Ejemplo de un modal reutilizable con JavaScript Vanilla y Tailwind CSS
3 de julio de 2026
JavaScript
·Tailwind CSS
·HTML

Cómo crear un modal reutilizable con JavaScript Vanilla y Tailwind CSS

Diseña un componente modal sólido, accesible y configurable sin depender de frameworks, usando clases utilitarias de Tailwind CSS.

Fotografía de Unsplash creada por Carter Obasohan
Imagen del articulo Tooltip reutilizable creado con JavaScript Vanilla
3 de julio de 2026
HTML
·JavaScript

Creando un Tooltip reutilizable con JavaScript Vanilla

Aprende a construir un sistema de tooltips flexible, accesible y controlable sin depender de librerías externas.

Fotografía de Unsplash creada por Marek Piwnicki
Imagen del articulo Modal reutilizable creado con JavaScript Vanilla y TypeScript
27 de junio de 2026
HTML
·JavaScript

Creando un modal reutilizable con JavaScript Vanilla para tu proyecto

Aprende a construir un sistema de modales flexible, reutilizable y controlable sin depender de librerías externas.