Atributos

Los atributos se analizaron brevemente en la Descripción general de HTML; es hora de profundizar más.

Los atributos son los que hacen que HTML sea tan poderoso. Los atributos son nombres separados por espacios y pares nombre/valor que aparecen en la etiqueta de apertura y proporcionan información acerca del elemento y su funcionalidad.

Etiqueta de apertura, atributos y etiqueta de cierre, etiquetados en un elemento HTML.

Los atributos definen el comportamiento, las vinculaciones y la funcionalidad de los elementos. Algunos atributos son globales, es decir, pueden aparecer dentro de la etiqueta de apertura de cualquier elemento. Otros atributos se aplican a varios elementos, pero no a todos, mientras que otros son específicos del elemento y son relevantes solo para un único elemento. En HTML, todos los atributos, excepto los booleanos y, en cierta medida, los que se indican, requieren un valor.

Si el valor de un atributo incluye espacios o caracteres especiales, el valor debe estar entre comillas. Por este motivo, y para mejorar la legibilidad, siempre se recomienda usar comillas.

Si bien el formato HTML no distingue mayúsculas de minúsculas, algunos valores de atributos sí lo hacen. Los valores que forman parte de la especificación HTML no distinguen mayúsculas de minúsculas. Los valores de cadenas que se definen, como los nombres de clase e ID, distinguen mayúsculas de minúsculas. Si el valor de un atributo distingue mayúsculas de minúsculas en HTML, lo hace cuando se usa como parte de un selector de atributos en CSS y en JavaScript. De lo contrario, no lo es.

<!-- the type attribute is case insensitive: these are equivalent -->
<input type="text">
<input type="TeXt">

<!-- the id attribute is case sensitive: they are not equivalent -->
<div id="myId">
<div id="MyID">

Atributos booleanos

Si hay un atributo booleano, siempre es verdadero. Los atributos booleanos incluyen autofocus, inert, checked, disabled, required, reversed, allowfullscreen, default, loop, autoplay, controls, muted, readonly, multiple, y selected. Si uno (o más) de estos atributos está presente, el elemento está inhabilitado, obligatorio, solo lectura, etc. Si no está presente, no lo está.

Los valores booleanos se pueden omitir, establecer como una string vacía o ser el nombre del atributo, pero no es necesario que el valor se configure realmente en la string true. Todos los valores, incluidos true, false y 😀, aunque no sean válidos, se resolverán como verdaderos.

Estas tres etiquetas son equivalentes:

<input required>
<input required="">
<input required="required">

Si el valor del atributo es falso, omite el atributo. Si el atributo es verdadero, inclúyelo, pero no proporcione ningún valor. Por ejemplo, required="required" no es un valor válido en HTML; pero como required es booleano, los valores no válidos se resuelven en verdadero. Sin embargo, como los atributos enumerados no válidos no necesariamente se resuelven con el mismo valor que los valores faltantes, es más fácil adoptar el hábito de omitir valores que recordar qué atributos son booleanos y cuáles están enumerados y, potencialmente, proporcionar un valor no válido.

Cuando alternes entre verdadero y falso, agrega y quita el atributo por completo con JavaScript, en lugar de activar o desactivar el valor.

const myMedia = document.getElementById("mediaFile");
myMedia.removeAttribute("muted");
myMedia.setAttribute("muted");

Ten en cuenta que en los lenguajes XML, como SVG, todos los atributos deben incluir un valor, incluidos los atributos booleanos.

Atributos enumerados

Los atributos enumerados a veces se confunden con los atributos booleanos. Son atributos HTML que tienen un conjunto limitado de valores válidos predefinidos. Al igual que los atributos booleanos, tienen un valor predeterminado si el atributo está presente, pero falta el valor. Por ejemplo, si incluyes <style contenteditable>, el valor predeterminado es <style contenteditable="true">.

Sin embargo, a diferencia de los atributos booleanos, omitir el atributo no significa que sea falso. Un atributo presente con un valor faltante no necesariamente es verdadero y el valor predeterminado para valores no válidos no necesariamente es lo mismo que una string nula. Para continuar con el ejemplo, contenteditable tiene el valor predeterminado inherit si falta o no es válido, y puede establecerse de manera explícita como false.

El valor predeterminado depende del atributo. A diferencia de los valores booleanos, los atributos no son automáticamente "true" si están presentes. Si incluyes <style contenteditable="false">, no se podrá editar el elemento. Si el valor no es válido, como <style contenteditable="😀"> o, sorprendentemente, <style contenteditable="contenteditable">, el valor no es válido y se establece de forma predeterminada como inherit.

En la mayoría de los casos con atributos enumerados, los valores faltantes y no válidos son los mismos. Por ejemplo, si falta el atributo type en una <input>, está presente pero sin un valor, o tiene un valor no válido, el valor predeterminado es text. Si bien este comportamiento es común, no es una regla. Por lo tanto, es importante saber qué atributos son booleanos y cuáles son enumerados, omitir los valores si es posible para evitar errores y buscar el valor según sea necesario.

Atributos globales

Los atributos globales son atributos que se pueden configurar en cualquier elemento HTML, incluidos los elementos de <head>. Hay más de 30 atributos globales. Si bien, en teoría, todos estos se pueden agregar a cualquier elemento HTML, algunos atributos globales no tienen efecto cuando se configuran en algunos elementos; por ejemplo, configurar hidden en una <meta> porque no se muestra el metacontenido.

id

El atributo global id se usa para definir un identificador único para un elemento. Sirve para muchos propósitos, incluidos los siguientes: - El destino del identificador de fragmento de un vínculo - Identificar un elemento para la creación de secuencias de comandos. - Asociar un elemento del formulario con su etiqueta. - Proporcionar una etiqueta o descripción para las tecnologías de asistencia. - Estilos de segmentación con (alta especificidad o como selectores de atributos) en CSS

El valor id es una string sin espacios. Si contiene un espacio, el documento no se romperá, pero tendrás que segmentar id con caracteres de escape en tu HTML, CSS y JS. Todos los demás caracteres son válidos. Un valor id puede ser 😀 o .class, pero no es una buena idea. Para facilitar la programación a tu yo actual y futuro, haz que el primer carácter de id sea una letra y usa solo letras, dígitos, _ y - en formato ASCII. Se recomienda crear una convención de nombres de id y, luego, mantenerla, ya que los valores de id distinguen mayúsculas de minúsculas.

El elemento id debe ser único para el documento. Es probable que el diseño de tu página no falle si se usa id más de una vez, pero es posible que las interacciones de JavaScript, los vínculos y los elementos no funcionen como se espera.

La barra de navegación incluye cuatro enlaces. Abordaremos el elemento de vínculo más adelante, pero, por ahora, ten en cuenta que los vínculos no están restringidos a URLs basadas en HTTP, sino que pueden ser identificadores de fragmentos de secciones de la página en el documento actual (o en otros documentos).

En el sitio del taller de aprendizaje automático, la barra de navegación en el encabezado de página incluye cuatro vínculos:

El atributo href proporciona el hipervínculo al que se dirige al usuario cuando se activa el vínculo. Cuando una URL incluye una marca de hash (#) seguida de una string de caracteres, esa string es un identificador de fragmento. Si esa string coincide con un id de un elemento de la página web, el fragmento es un ancla o un favorito a ese elemento. El navegador se desplazará hasta el punto en el que se definió el ancla.

Estos cuatro vínculos dirigen a cuatro secciones de nuestra página identificadas por su atributo id. Cuando el usuario hace clic en cualquiera de los cuatro vínculos de la barra de navegación, se desplaza a la vista el elemento vinculado por el identificador de fragmento (el elemento que contiene el ID coincidente menos el #).

El contenido de <main> del taller de aprendizaje automático tiene cuatro secciones con IDs. Cuando el visitante del sitio hace clic en uno de los vínculos en <nav>, la sección con ese identificador de fragmento se desplaza a la vista. La marca es similar a lo siguiente:

<section id="reg">
  <h2>Machine Learning Workshop Tickets</h2>
</section>

<section id="about">
  <h2>What you'll learn</h2>
</section>

<section id="teachers">
  <h2>Your Instructors</h2>
  <h3>Hal 9000 <span>&amp;</span> EVE</h3>
</section>

<section id="feedback">
  <h2>What it's like to learn good and do other stuff good too</h2>
</section>

Si comparas los identificadores de fragmentos en los vínculos de <nav>, notarás que cada uno coincide con el id de un <section> en <main>. El navegador nos proporciona un vínculo gratuito para la parte superior de la página. Si se configura href="#top", que no distingue entre mayúsculas y minúsculas, o simplemente href="#", el usuario se desplazará a la parte superior de la página.

El separador de marca de hash en href no forma parte del identificador de fragmento. El identificador de fragmento siempre es la última parte de la URL y no se envía al servidor.

Selectores CSS

En CSS, puedes segmentar cada sección mediante un selector de ID, como #feedback, o, para un menor especificidad, un selector de atributos que distingue mayúsculas de minúsculas, [id="feedback"].

Guion

En MLW.com, hay un huevo de pascua solo para usuarios de mouse. Haz clic en el interruptor de luz para activar o desactivar la página.

El lenguaje de marcado de la imagen del interruptor de luz es el siguiente: html <img src="svg/switch2.svg" id="switch" alt="light switch" class="light" /> El atributo id se puede usar como parámetro para el método getElementById() y, con un prefijo #, como parte de un parámetro para los métodos querySelector() y querySelectorAll().

const switchViaID = document.getElementById("switch");
const switchViaSelector = document.querySelector("#switch");

Nuestra función única de JavaScript usa esta capacidad de orientar elementos por su atributo id:

<script>
  /* switch is a reserved word in js, so we us onoff instead */
  const onoff = document.getElementById('switch');
  onoff.addEventListener('click', function(){
    document.body.classList.toggle('black');
  });
</script>

<label>

El elemento HTML <label> tiene un atributo for que toma como valor el id del control de formulario con el que está asociado. Crear una etiqueta explícita con la inclusión de un id en cada control de formulario y vincular cada uno con el atributo for de la etiqueta garantiza que cada control de formulario tenga una etiqueta asociada.

Si bien cada etiqueta se puede asociar con exactamente un control de formulario, un control de formulario puede tener más de una etiqueta asociada.

Si el control de formulario está anidado entre las etiquetas de apertura y cierre <label>, no se requieren los atributos for ni id, lo que se denomina una etiqueta "implícita". Las etiquetas permiten que todos los usuarios sepan para qué sirve cada control de formulario.

<label>
  Send me a reminder <input type="number" name="min"> before the workshop resumes
</label>.

La asociación entre for y id pone la información a disposición de los usuarios de tecnologías de accesibilidad. Además, cuando se hace clic en cualquier parte de una etiqueta, se enfoca el elemento asociado, lo que extiende el área de clic del control. Esto no solo es útil para las personas con problemas de destreza que hacen que el mouse sea menos preciso, sino que también ayuda a todos los usuarios de dispositivos móviles con los dedos más anchos que un botón de selección.

En este ejemplo de código, la quinta pregunta falsa de un cuestionario falso es una pregunta de opción múltiple de selección única. Cada control de formulario tiene una etiqueta explícita, con un id único para cada uno. Para garantizar que no dupliquemos un ID accidentalmente, el valor del ID es una combinación del número de pregunta y el valor.

Cuando se incluyen los botones de selección, ya que las etiquetas describen el valor de estos botones, englobamos todos los botones con el mismo nombre en una <fieldset>, y <legend> es la etiqueta, o pregunta, para todo el conjunto.

Otros usos de accesibilidad

El uso de id en accesibilidad y usabilidad no se limita a las etiquetas. En la introducción al texto, un <section> se convirtió en un punto de referencia de la región haciendo referencia a id de un <h2> como el valor de aria-labelledby de <section> para proporcionar el nombre de accesibilidad:

<section id="about" aria-labelledby="about_heading">
<h2 id="about_heading">What you'll learn</h2>

Existen más de 50 estados y propiedades de aria-* que se pueden usar para garantizar la accesibilidad. aria-labelledby, aria-describedby, aria-details y aria-owns toman como valor una lista de referencia id separada por espacios. aria-activedescendant, que identifica el elemento descendiente enfocado actualmente, toma como valor una sola referencia de id: la del único elemento que está enfocado (solo se puede enfocar un elemento a la vez).

class

El atributo class proporciona una forma adicional de segmentar elementos con CSS (y JavaScript), pero no tiene ningún otro propósito en HTML (aunque los frameworks y las bibliotecas de componentes pueden usarlos). El atributo de clase toma como valor una lista separada por espacios de las clases del elemento que distinguen mayúsculas de minúsculas.

Crear una estructura semántica sólida permite segmentar los elementos según su ubicación y función. La estructura de sonido permite el uso de selectores de elementos subordinados, selectores relacionales y de atributos. A medida que aprendas sobre los atributos en esta sección, considera cómo se pueden aplicar estilos a los elementos con los mismos atributos o valores de atributos. No es que no debas usar el atributo de clase, sino que la mayoría de los desarrolladores no se dan cuenta de que, a menudo, no necesitan hacerlo.

Hasta ahora, MLW no ha usado ninguna clase. ¿Se puede iniciar un sitio sin un solo nombre de clase? Ya veremos.

style

El atributo style permite aplicar estilos intercalados, que son estilos aplicados al único elemento en el que se configura el atributo. El atributo style toma como sus pares de valor de propiedad de CSS, y la sintaxis del valor es la misma que el contenido de un bloque de estilo CSS: las propiedades van seguidas de dos puntos, al igual que en CSS, y el punto y coma termina cada declaración, después del valor.

Los estilos solo se aplican al elemento en el que se configura el atributo, y los elementos subordinados heredan valores de propiedad heredados si no los anulan otras declaraciones de diseño de elementos anidados, hojas de estilo o bloques <style>. Como el valor comprende el equivalente del contenido de un único bloque de estilo aplicado solo a ese elemento, no se puede usar para el contenido generado, para crear animaciones de fotogramas clave ni para aplicar ninguna otra regla at.

Si bien style es un atributo global, no se recomienda usarlo. En cambio, define los estilos en uno o varios archivos independientes. Dicho esto, el atributo style puede ser útil durante el desarrollo para habilitar un estilo rápido, por ejemplo, para realizar pruebas. Luego, toma el estilo de la “solución” y guárdalo en el archivo CSS vinculado.

tabindex

Se puede agregar el atributo tabindex a cualquier elemento para habilitarlo y recibir el foco. El valor tabindex define si se agrega al orden de tabulación y, de forma opcional, en un orden de tabulación no predeterminado.

El atributo tabindex toma como valor un número entero. Un valor negativo (la convención es usar -1) hace que un elemento pueda recibir el foco, como a través de JavaScript, pero no lo agrega a la secuencia de tabulación. Un valor tabindex de 0 hace que el elemento sea enfocable y accesible con el tabulador, y lo agrega al orden de tabulación predeterminado de la página en el orden del código fuente. Un valor de 1 o más coloca el elemento en una secuencia de enfoque priorizada y no se recomienda.

En esta página, hay una función para compartir con un elemento personalizado <share-action> que funciona como <button>. Se incluye el tabindex de cero para agregar el elemento personalizado en el orden de tabulación predeterminado del teclado:

<share-action authors="@estellevw" data-action="click" data-category="web.dev" data-icon="share" data-label="share, twitter" role="button" tabindex="0">
  <svg aria-label="share" role="img" xmlns="http://www.w3.org/2000/svg">
    <use href="#shareIcon" />
  </svg>
  <span>Share</span>
</share-action>

El role de button informa a los usuarios de lectores de pantalla que este elemento debe comportarse como un botón. Se usa JavaScript para garantizar que se mantenga la promesa de funcionalidad del botón, lo que incluye el control de los eventos de clic y keydown, así como el control de las pulsaciones de teclas Intro y Espacio.

Los controles de formulario, los vínculos, los botones y los elementos de contenido editable pueden recibir el foco. Cuando un usuario del teclado presiona la tecla Tab, el foco se mueve al siguiente elemento enfocable como si tuviera configurado tabindex="0". Otros elementos no se pueden enfocar de forma predeterminada. Agregar el atributo tabindex a esos elementos les permite recibir el foco cuando, de lo contrario, no lo harían.

Si un documento incluye elementos con un tabindex de 1 o más, se incluyen en una secuencia de pestañas independiente. Como observarás en el código, el tabulación comienza en una secuencia separada, en orden de valor más bajo a más alto, antes de pasar por las de la secuencia regular en orden de origen.

Alterar el orden de tabulación puede crear una experiencia del usuario realmente mala. Resulta difícil depender de la tecnología de asistencia (tanto los teclados como los lectores de pantalla) para navegar por el contenido. También es difícil de administrar y mantener como desarrollador. El enfoque es importante; hay todo un módulo en el que se analiza el enfoque y su orden.

role

El atributo role forma parte de la especificación de ARIA, en lugar de la especificación de HMTL de WhatWG. Se puede usar el atributo role para proporcionar significado semántico al contenido, lo que permite que los lectores de pantalla informen a los usuarios del sitio sobre la interacción esperada del usuario de un objeto.

Hay algunos widgets de IU comunes, como cuadros combinados, barras de menú, tablistas y cuadrículas de árbol, que no tienen un equivalente HTML nativo. Por ejemplo, cuando se crea un patrón de diseño con pestañas, se pueden usar las funciones tab, tablist y tabpanel. Alguien que puede ver físicamente la interfaz de usuario aprendió por experiencia cómo navegar por el widget y hacer clic en las pestañas asociadas para que diferentes paneles sean visibles. Incluir la función tab con <button role="tab"> cuando se usa un grupo de botones para mostrar diferentes paneles permite que el usuario del lector de pantalla sepa que el <button> que está enfocado actualmente puede mostrar un panel relacionado en lugar de implementar una funcionalidad típica similar a un botón.

El atributo role no cambia el comportamiento del navegador ni altera las interacciones con el teclado o el dispositivo apuntador: agregar role="button" a un <span> no lo convierte en un <button>. Por esta razón, se recomienda usar elementos HTML semánticos para su propósito previsto. Sin embargo, cuando no es posible usar el elemento correcto, el atributo role permite informar a los usuarios de lectores de pantalla cuando un elemento no semántico se actualizó a la función de un elemento semántico.

contenteditable

Un elemento con el atributo contenteditable configurado como true se puede editar, es enfocable y se agrega al orden de tabulación como si se configurara tabindex="0". Contenteditable es un atributo enumerado que admite los valores true y false, con un valor predeterminado de inherit si el atributo no está presente o tiene un valor no válido.

Estas tres etiquetas de apertura son equivalentes:

<style contenteditable>
<style contenteditable="">
<style contenteditable="true">

Si incluyes <style contenteditable="false">, no podrás editar el elemento (a menos que se pueda editar de forma predeterminada, como <textarea>). Si el valor no es válido (como <style contenteditable="😀"> o <style contenteditable="contenteditable">), su valor predeterminado es inherit.

Para alternar entre estados, consulta el valor de la propiedad de solo lectura HTMLElement.isContentEditable.

const editor = document.getElementById("myElement");
if(editor.contentEditable) {
  editor.setAttribute("contenteditable", "false");
} else {
  editor.setAttribute("contenteditable", "");
}

Como alternativa, esta propiedad se puede especificar si estableces editor.contentEditable en true, false o inherit.

Los atributos globales se pueden aplicar a todos los elementos, incluso a los <style>. Puedes usar atributos y un poco de CSS para crear un editor de CSS activo.

<style contenteditable>
style {
  color: inherit;
  display:block;
  border: 1px solid;
  font: inherit;
  font-family: monospace;
  padding:1em;
  border-radius: 1em;
  white-space: pre;
}
</style>

Intenta cambiar el color de style a uno que no sea inherit. Luego, intenta cambiar el style a un selector p. No quites la propiedad de visualización; de lo contrario, el bloque de estilo desaparecerá.

Atributos personalizados

Solo vimos la superficie de los atributos globales de HTML. Existen incluso más atributos que se aplican a un solo elemento o a un conjunto limitado de ellos. Incluso con cientos de atributos definidos, es posible que necesites un atributo que no esté en la especificación. HTML tiene lo que necesitas.

Puedes crear el atributo personalizado que quieras agregando el prefijo data-. Puedes asignar cualquier nombre al atributo que comience con data- seguido de cualquier serie de caracteres en minúscula que no comience con xml y no contengan dos puntos (:).

Si bien HTML es permisivo y no se rompe si creas atributos no compatibles que no comienzan con data, o incluso si comienzas tu atributo personalizado con xml o incluyes un :, existen beneficios en crear atributos personalizados válidos que comiencen con data-. Con los atributos de datos personalizados, sabe que no está usando accidentalmente un nombre de atributo existente. Los atributos de datos personalizados están preparados para el futuro.

Si bien los navegadores no implementarán comportamientos predeterminados para ningún atributo específico con el prefijo data-, existe una API de conjunto de datos integrada para iterar a través de tus atributos personalizados. Las propiedades personalizadas son una excelente manera de comunicar información específica de la aplicación a través de JavaScript. Agrega atributos personalizados a los elementos en forma de data-name y accede a ellos a través del DOM usando dataset[name] en el elemento en cuestión.

<blockquote data-machine-learning="workshop"
  data-first-name="Blendan" data-last-name="Smooth"
  data-formerly="Margarita Maker" data-aspiring="Load Balancer"
  data-year-graduated="2022">
  HAL and EVE could teach a fan to blow hot air.
</blockquote>

Puedes usar getAttribute() con el nombre completo del atributo o aprovechar la propiedad dataset más simple.

el.dataset[machineLearning]; // workshop
e.dataset.machineLearning; // workshop

La propiedad dataset muestra un objeto DOMStringMap de los atributos data- de cada elemento. Hay varios atributos personalizados en <blockquote>. La propiedad del conjunto de datos implica que no necesitas saber cuáles son esos atributos personalizados para acceder a sus nombres y valores:

for (let key in el.dataset) {
  customObject[key] = el.dataset[key];
}

Los atributos que se mencionan en este artículo son globales, lo que significa que se pueden aplicar a cualquier elemento HTML (aunque no todos afectan a esos elementos). A continuación, analizaremos los dos atributos de la imagen de introducción que no abordamos, target ni href, y muchos otros atributos específicos del elemento a medida que profundizamos en los vínculos.

Verifica tus conocimientos

Pon a prueba tus conocimientos sobre los atributos.

Un id debe ser único en el documento.

Falso
Vuelve a intentarlo.
Verdadero
Correcto.

Selecciona el atributo personalizado con el formato correcto.

data-birthday
Correcta
birthday
Vuelve a intentarlo.
data:birthday
Reintentar