Atributos

Los atributos se analizaron brevemente en la descripción general de HTML. Es hora de profundizar.

Los atributos son lo que hace que el HTML sea tan potente. Los atributos son nombres y pares nombre/valor separados por espacios que aparecen en la etiqueta de apertura y proporcionan información y funcionalidad para el elemento.

La etiqueta de apertura, los atributos y la etiqueta de cierre etiquetados en un elemento HTML

Los atributos definen el comportamiento, los vínculos y la funcionalidad de los elementos. Algunos atributos son globales, lo que significa que 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 de un elemento y solo son relevantes para un solo elemento. En HTML, todos los atributos, excepto los booleanos y, en cierta medida, los enumerados, requieren un valor.

Si un valor de atributo incluye un espacio 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 código HTML no distingue mayúsculas de minúsculas, algunos valores de atributos sí lo hacen. Los valores que forman parte de la especificación de HTML no distinguen mayúsculas de minúsculas. Los valores de cadenas definidos, como los nombres de clase y de ID, distinguen mayúsculas de minúsculas. Si un valor de atributo distingue mayúsculas de minúsculas en HTML, también lo hace cuando se usa como parte de un selector de atributos en CSS y en JavaScript. De lo contrario, no lo hace.

<!-- 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, es obligatorio, de solo lectura, etc. Si no está presente, no lo es.

Los valores booleanos se pueden omitir, establecer en una cadena vacía o ser el nombre del atributo, pero el valor no tiene que establecerse en la cadena 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, omítelo. Si el atributo es verdadero, inclúyelo, pero no proporciones un 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 como verdaderos. Sin embargo, como los atributos enumerados no válidos no siempre se resuelven en el mismo valor que los valores faltantes, es más fácil adquirir el hábito de omitir valores que recordar qué atributos son booleanos en lugar de enumerados y, potencialmente, proporcionar un valor no válido.

Cuando cambies entre verdadero y falso, agrega y quita el atributo por completo con JavaScript en lugar de cambiar 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

A veces, los atributos enumerados 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>, se establecerá de forma predeterminada como <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 es necesariamente verdadero, y el valor predeterminado para los valores no válidos no es necesariamente el mismo que una cadena nula. Siguiendo con el ejemplo, el valor predeterminado de contenteditable es inherit si falta o no es válido, y se puede establecer de forma explícita en false.

El valor predeterminado depende del atributo. A diferencia de los valores booleanos, los atributos no se establecen automáticamente como "verdaderos" si están presentes. Si incluyes <style contenteditable="false">, el elemento no se puede editar. 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 en 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 un <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 este motivo, es importante saber qué atributos son booleanos y cuáles enumerados. Si es posible, omite los valores para no equivocarte y búscalos 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 se pueden agregar a cualquier elemento HTML, algunos atributos globales no tienen efecto cuando se configuran en algunos elementos; por ejemplo, no se muestra hidden en un <meta> como metacontenido.

id

El atributo global id se usa para definir un identificador único para un elemento. Sirve para muchos fines, como los siguientes: - El destino del identificador de fragmento de un vínculo. - Identificar un elemento para la escritura de secuencias de comandos - Asocia un elemento de formulario con su etiqueta. - Proporcionar una etiqueta o descripción para las tecnologías de accesibilidad - Segmentación de estilos con (alta especificidad o como selectores de atributos) en CSS.

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

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

La barra de navegación incluye cuatro vínculos. Más adelante, hablaremos del elemento vínculo, pero por ahora, ten en cuenta que los vínculos no se limitan a las URLs basadas en HTTP; pueden ser identificadores de fragmentos para 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 la página incluye cuatro vínculos:

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

Estos cuatro vínculos apuntan 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 al que hace referencia el identificador de fragmento, el elemento que contiene el ID coincidente menos el #.

El contenido <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 de <nav>, la sección con ese identificador de fragmento se desplaza hasta aparecer en la vista. El lenguaje de marcado es similar al 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 fragmento en los vínculos <nav>, notarás que cada uno coincide con el id de un <section> en <main>. El navegador nos proporciona un vínculo gratuito de "parte superior de la página". Si configuras href="#top", sin distinción de mayúsculas o minúsculas, o simplemente href="#", el usuario se desplazará a la parte superior de la página.

El separador 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 con un selector de ID, como #feedback o, para menos especificidad, un selector de atributo, [id="feedback"], que distingue mayúsculas de minúsculas.

Guion

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

El 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 única función de JavaScript usa esta capacidad para segmentar 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 <label> HTML tiene un atributo for que toma como valor el id del control de formulario con el que está asociado. Crear una etiqueta explícita mediante 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 de <label>, los atributos for y id no son obligatorios: esto se denomina 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, hacer clic en cualquier lugar de una etiqueta enfoca el elemento asociado y extiende el área de clic del control. Esto no solo es útil para las personas con problemas de destreza que hacen que el uso del mouse sea menos preciso, sino que también ayuda a todos los usuarios de dispositivos móviles con dedos más anchos que un botón de radio.

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

Cuando se incluyen botones de selección, como las etiquetas describen el valor de los botones de selección, abarcamos todos los botones con el mismo nombre en un <fieldset>, en el que <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, se convirtió un <section> en un punto de referencia de región haciendo referencia al id de un <h2> como el valor del aria-labelledby de <section> para proporcionar el nombre accesible:

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

Hay 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 referencias id separada por espacios. aria-activedescendant, que identifica el elemento descendiente enfocado actualmente, toma como valor una sola referencia id: la del elemento único que tiene el enfoque (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 que distinguen mayúsculas de minúsculas del elemento.

La creación de una estructura semántica sólida permite segmentar elementos según su ubicación y función. La estructura de sonido permite el uso de selectores de elementos secundarios, selectores relacionales y selectores 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 es necesario.

Hasta el momento, MLW no usó ninguna clase. ¿Se puede iniciar un sitio sin un solo nombre de clase? Ya lo veremos.

style

El atributo style permite aplicar estilos intercalados, que son estilos aplicados al único elemento en el que se establece el atributo. El atributo style toma como valor pares de valores de propiedades CSS, con la sintaxis del valor igual al contenido de un bloque de estilo CSS: las propiedades están seguidas de dos puntos, al igual que en CSS, y los puntos y comas terminan cada declaración, después del valor.

Los estilos solo se aplican al elemento en el que se establece el atributo, y los elementos secundarios heredan los valores de propiedad heredados si no se anulan con otras declaraciones de estilo en elementos anidados o en bloques o hojas de estilo <style>. Como el valor comprende el equivalente del contenido de un solo 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 su lugar, define los estilos en un archivo o archivos separados. Dicho esto, el atributo style puede ser útil durante el desarrollo para habilitar estilos rápidos, por ejemplo, para pruebas. Luego, toma el estilo de la "solución" y pégalo en tu archivo CSS vinculado.

tabindex

El atributo tabindex se puede agregar a cualquier elemento para que pueda recibir el enfoque. El valor tabindex define si se agrega al orden de tabulación y, de manera opcional, a 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 sea capaz de recibir el enfoque, por ejemplo, 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 accesible y se pueda enfocar mediante la tabulación, y lo agrega al orden de tabulación predeterminado de la página en orden de 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 de compartir que usa un elemento personalizado <share-action> que actúa como <button>. Se incluye el tabindex de cero para agregar el elemento personalizado al 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 cumpla la promesa de funcionalidad del botón, lo que incluye controlar los eventos click y keydown, así como 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 enfoque. Cuando un usuario del teclado presiona la tecla Tab, el enfoque se mueve al siguiente elemento que se puede enfocar como si se hubiera configurado tabindex="0". Otros elementos no son enfocables de forma predeterminada. Agregar el atributo tabindex a esos elementos les permite recibir el foco cuando, de otro modo, no lo harían.

Si un documento incluye elementos con un tabindex de 1 o más, se incluyen en una secuencia de tabulación independiente. Como verás en CodePen, la tabulación comienza en una secuencia independiente, en orden del valor más bajo al más alto, antes de pasar por los de la secuencia normal en orden de origen.

Alterar el orden de tabulación puede generar una experiencia del usuario muy mala. Esto dificulta el uso de la tecnología de accesibilidad, como teclados y lectores de pantalla, para navegar por tu contenido. También es difícil para los desarrolladores administrar y mantener. El enfoque es importante. Hay un módulo completo sobre el enfoque y el orden de enfoque.

role

El atributo role forma parte de la especificación ARIA, en lugar de la especificación HTML de WHATWG. El atributo role se puede usar 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 con un objeto.

Hay algunos widgets de IU comunes, como comboboxes, barras de menú, listas de tablas y tablas 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 los roles tab, tablist y tabpanel. Una persona que puede ver físicamente la interfaz de usuario aprendió por experiencia a navegar por el widget y hacer que diferentes paneles sean visibles haciendo clic en las pestañas asociadas. Si se incluye el rol tab con <button role="tab"> cuando se usa un grupo de botones para mostrar diferentes paneles, el usuario del lector de pantalla sabe que el <button> que tiene el enfoque actualmente puede activar o desactivar un panel relacionado en lugar de implementar la funcionalidad típica de botón.

El atributo role no cambia el comportamiento del navegador ni altera las interacciones del teclado o del dispositivo de puntero. Si agregas role="button" a un <span>, no se convierte en <button>. Por este motivo, 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 adaptó al rol de un elemento semántico.

contenteditable

Un elemento con el atributo contenteditable configurado en true se puede editar, enfocar y agregar al orden de tabulación como si se hubiera configurado 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">, el elemento no se puede editar (a menos que sea editable de forma predeterminada, como un <textarea>). Si el valor no es válido, como <style contenteditable="😀"> o <style contenteditable="contenteditable">, el 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, puedes especificar esta propiedad configurando editor.contentEditable como true, false o inherit.

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

<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 un valor que no sea inherit. Luego, intenta cambiar el style a un selector p. No quites la propiedad de visualización, o el bloque de estilo desaparecerá.

Atributos personalizados

Solo hemos tocado la superficie de los atributos globales de HTML. Hay aún más atributos que se aplican a uno o a un conjunto limitado de elementos. Incluso con cientos de atributos definidos, es posible que necesites un atributo que no esté en la especificación. HTML es la solución.

Puedes crear cualquier atributo personalizado que desees agregando el prefijo data-. Puedes nombrar tu atributo con cualquier nombre que comience con data- seguido de cualquier serie de caracteres en minúsculas que no comience con xml ni contenga dos puntos (:).

Si bien HTML es tolerante y no se romperá si creas atributos no admitidos que no comienzan con data, o incluso si comienzas tu atributo personalizado con xml o incluyes un :, hay beneficios en crear atributos personalizados válidos que comienzan con data-. Con los atributos de datos personalizados, sabes que no estás 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 prefijo data-, hay 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 con 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 significa 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 de este artículo son globales, lo que significa que se pueden aplicar a cualquier elemento HTML (aunque no todos tienen un impacto en esos elementos). A continuación, analizaremos los dos atributos de la imagen de introducción que no abordamos (target y href) y algunos otros atributos específicos de los elementos a medida que analizamos con mayor detalle los vínculos.

Verifica tu comprensión

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
Correcto
birthday
Vuelve a intentarlo.
data:birthday
Reintentar