¿Alguna vez has querido añadir datos personalizados a un elemento HTML concreto para poder acceder a ellos más tarde con JavaScript? Antes de que HTML5 apareciera en el mercado, almacenar datos personalizados asociados al DOM era un auténtico lío, y los desarrolladores tenían que recurrir a todo tipo de trucos desagradables, como introducir atributos no estándar o utilizar el obsoleto método setUserData()
para sortear el problema.
Por suerte, ya no es necesario, ya que HTML5 ha introducido nuevos atributos globales data-* que permiten incrustar información adicional en cualquier elemento HTML. Los nuevos atributos data-* hacen que HTML sea más extensible, lo que permite crear aplicaciones más complejas y una experiencia de usuario más sofisticada sin tener que recurrir a técnicas que consumen muchos recursos, como las llamadas Ajax o las consultas a bases de datos del servidor.
La compatibilidad de los nuevos atributos globales con los navegadores es relativamente buena, ya que son compatibles con todos los navegadores modernos (IE8-10 los admite parcialmente).
Sintaxis de los Atributos data-*
La sintaxis de los nuevos atributos data-* es similar a la de los atributos aria-prefijado. Puede insertar cualquier cadena en minúsculas en lugar del signo *. También es necesario asignar un valor a cada atributo en forma de cadena.
Supongamos que deseas crear una página Quiénes somos y almacenar el nombre del departamento en el que trabaja cada empleado. No tienes que hacer nada más aparte de añadir el atributo personalizado data-department al elemento HTML apropiado de la siguiente manera:
<ul>
<li data-department="Marketing">
John Doe
</li>
<li data-department="IT">
Jane Doe
</li>
</ul>
Los atributos data-* personalizados son globales, al igual que los atributos class e id, por lo que puedes utilizarlos en todos los elementos HTML. También puedes añadir tantos atributos data-*
a una etiqueta HTML como quieras. En el ejemplo anterior, por ejemplo, puedes introducir un nuevo atributo personalizado llamado data-user
para almacenar los nombres de usuario de los empleados.
<ul>
<li id="john" class="employee" data-department="Marketing"
data-user="johndoe">
John Doe
</li>
<li id="jane" class="employee" data-department="IT"
data-user="janedoe">
Jane Doe
</li>
</ul>
Como regla general, si quieres añadir tu propio atributo personalizado a un elemento HTML, siempre tienes que anteponerle la cadena data-. Del mismo modo, cuando veas un atributo prefijado con data en el código de otra persona, puedes estar seguro de que se trata de un atributo personalizado introducido por el autor.
Cuándo Usar y Cuándo No Usar Atributos Personalizados
El W3C define los atributos de datos personalizados-* de la siguiente manera:
“Los atributos de datos personalizados están pensados para almacenar datos personalizados privados de la página o aplicación, para los que no existen atributos o elementos más apropiados.”
W3C
Merece la pena considerar el uso de atributos data-* cuando no encuentres otros atributos semánticos para los datos que quieres almacenar.
No es una buena idea utilizarlos únicamente con fines de estilización, ya que para eso puedes elegir entre los atributos class
y style
. Si quieres almacenar un tipo de dato para el que HTML5 tiene un atributo semántico, como el atributo datetime
para el elemento <time>
, utilízalo en lugar del atributo prefijado data.
Es importante tener en cuenta que los atributos data-* contienen datos privados de la página o la aplicación, lo que significa que serán ignorados por los agentes de usuario (user agents), como los robots de los motores de búsqueda y las aplicaciones externas. A los atributos data-* sólo puede acceder el código que se ejecuta en el sitio que aloja el HTML.
Los atributos data-* personalizados también son muy utilizados por los frameworks frontend, como Bootstrap y Zurb Foundation. La buena noticia es que no tienes por qué saber escribir JavaScript si quieres utilizar atributos data-prefijado como parte de un framework, ya que sólo tienes que añadirlos al código HTML para activar una funcionalidad de un plugin JavaScript preescrito.
El siguiente fragmento de código añade un tooltip a la izquierda a un botón en Bootstrap haciendo uso de los atributos personalizados data-toggle
y data-placement
, y asignándoles los valores apropiados.
<button type="button" class="btn btn-default" data-toggle="tooltip"
data-placement="left" title="Tooltip on left">
Tooltip a la izquierda
</button>
Seleccionar Atributos data-* con CSS
Aunque no se recomienda utilizar los atributos data-* sólo con fines estilísticos, puedes seleccionar los elementos HTML a los que pertenecen con la ayuda de selectores de atributos generales. Si quieres seleccionar cada elemento que tenga un determinado atributo data-*, utiliza esta sintaxis en tu CSS:
li[data-user] {
color: blue;
}
Ten en cuenta que no son los nombres de usuario los que se mostrarán en azul en el fragmento de código anterior -después de todo los datos almacenados en los atributos personalizados no son visibles- sino los nombres de los empleados contenidos en los elementos <li>
(en el ejemplo “John Doe” y “Jane Doe”).
Si sólo deseas seleccionar elementos en los que un atributo data-prefijado toma un determinado valor, ésta es la sintaxis que debes utilizar:
li[data-department="IT"] {
border: solid blue 1px;
}
Puedes utilizar todos los selectores de atributos CSS más complicados, como el selector combinador general de hermanos ([dato-valor~="foo"]
) o el selector comodín ([dato-valor*="foo"]
), también con atributos prefijados por datos.
Acceso a Atributos data-* con JavaScript
Puedes acceder a los datos almacenados en los atributos data-* personalizados con JavaScript utilizando la propiedad dataset o el método data()
de jQuery.
Vanilla JavaScript
La propiedad dataset
es una propiedad de la interfaz HTMLElement
, lo que significa que puede utilizarse en cualquier etiqueta HTML. La propiedad dataset
da acceso a todos los atributos data-* personalizados del elemento HTML dado. Los atributos se devuelven como un objeto DOMStringMap
que contiene una entrada por cada atributo data-*.
En nuestro ejemplo de la página Quiénes somos puedes comprobar fácilmente los atributos personalizados que tiene “Jane Doe” utilizando la propiedad dataset
de la siguiente manera:
var jane = document.getElementById("jane");
console.log(jane.dataset);
// DOMStringMap { user: "janedoe", department: "IT" }
Puedes ver que en el objeto DOMStringMap devuelto se han eliminado los prefijos data- de los nombres de los atributos (user en lugar de data-user, y department en lugar de data-department). Debes utilizar los atributos con el mismo formato si sólo quieres acceder al valor de un determinado atributo con prefijo data (en lugar de a la lista de todos los atributos personalizados como en el fragmento de código anterior).
Puedes recuperar el valor de un atributo data-* específico como una propiedad de la propiedad dataset. Como mencioné antes, necesitas omitir el prefijo data- del nombre de la propiedad, así que si quieres acceder al valor del atributo data-user de Jane, puedes hacerlo de esta manera:
var jane = document.getElementById("jane");
console.log(jane.dataset.user)
// janedoe
Método data() de jQuery
El método data()
de jQuery permite obtener el valor de un atributo con prefijo data. Aquí también hay que omitir el prefijo data- del nombre del atributo para acceder a él correctamente. En nuestro ejemplo, puedes mostrar un mensaje de alerta con el nombre del departamento donde trabaja “Jane” con el siguiente código:
$("#jane").hover( function() {
var department = $("#jane").data("department");
alert(department);
});
El método data() debe utilizarse con cuidado, ya que no sólo sirve para obtener el valor de un atributo con prefijo data, sino también para adjuntar datos a un elemento DOM de la siguiente manera:
var town = $("#jane").data("town", "New York");
Los datos extra que adjuntes con el método data() de jQuery obviamente no aparecerán en el código HTML como un nuevo atributo data-*, por lo que si se utilizan ambas técnicas al mismo tiempo, el elemento HTML dado almacenará dos conjuntos de datos, uno con HTML y otro con jQuery.
En nuestro ejemplo, “Jane” obtuvo un nuevo dato personalizado (“town”) con jQuery, pero este nuevo par clave-valor no aparecerá en HTML como un nuevo atributo data-town
. Almacenar datos de dos formas distintas no es la mejor práctica, por decirlo suavemente, así que utiliza sólo uno de los dos métodos a la vez.
Accesibilidad y Atributos data-*
Dado que los datos almacenados en los atributos data-* personalizados son privados, es posible que las tecnologías de asistencia no puedan acceder a ellos. Si quieres que tus contenidos sean accesibles para usuarios discapacitados, no es recomendable almacenar de esta forma contenidos que pueden ser importantes para los usuarios.