Addaw, ir a inicio Donar

Técnica HTML WCAG 2.2

H71Agrupar campos de formulario relacionados con fieldset y legend

Nombre oficial en el W3C: Proporcionar una descripción para los grupos de controles de formulario con los elementos fieldset y legend

En pocas palabras

Cuando varios campos responden a la misma pregunta, como las opciones «Sí» y «No», se agrupan con fieldset. La pregunta se escribe en legend. Así el lector de pantalla anuncia la pregunta al entrar en el grupo, y cada opción tiene sentido aunque se oiga sola.

Por qué es importante

A la vista, la pregunta y sus opciones forman un bloque. Pero un lector de pantalla (programa que lee en voz alta lo que hay en la pantalla) anuncia cada campo por separado. Si un formulario tiene tres preguntas de «Sí / No», la persona solo oye «Sí» o «No», sin saber a qué responde.

Con <fieldset> y <legend>, el lector dice la pregunta al entrar en el grupo. Esto ayuda en encuestas, en formularios de cita previa o al separar los datos de envío y de facturación.

Cómo se hace

  1. Envuelva cada grupo de botones de opción o de casillas relacionadas en un <fieldset>.
  2. Ponga la pregunta o el nombre del grupo en un <legend>, como primer elemento del fieldset.
  3. Mantenga un <label> en cada campo: el legend no lo sustituye.
  4. Escriba un legend corto, porque algunos lectores lo repiten en cada campo.
  5. Si no le gusta el borde, cambie su aspecto con CSS. No elimine el fieldset.

Ejemplo práctico

Hace falta en formularios con varias preguntas de «Sí / No» o con grupos de casillas, como una cita previa o una encuesta. Ahí la etiqueta de cada opción no dice, por sí sola, a qué pregunta pertenece.

Así no: Preguntas en párrafos sueltos

Cada pregunta es un p y cada grupo es un div. A la vista se entiende. Pero con el tabulador y el lector de pantalla solo se oye «Sí, botón de opción» o «No, botón de opción». No se sabe a qué pregunta corresponde.

Captura de pantalla del ejemplo incorrecto: Preguntas en párrafos sueltos
Así se ve el ejemplo incorrecto.

La demostración contiene, a propósito, el error de accesibilidad que se explica.

Ver el código del ejemplo incorrecto
<style>
  .grupo { border: 1px solid #767676; padding: 4px 12px 8px; margin: 0 0 12px; }
  .pregunta { font-weight: bold; margin: 4px 0; }
</style>
<form action="#">
  <div class="grupo">
    <p class="pregunta">¿Es su primera visita a la oficina?</p>
    <input type="radio" name="primera" id="primera-si" value="si">
    <label for="primera-si">Sí</label>
    <input type="radio" name="primera" id="primera-no" value="no">
    <label for="primera-no">No</label>
  </div>
  <div class="grupo">
    <p class="pregunta">¿Desea recibir un recordatorio por SMS?</p>
    <input type="radio" name="sms" id="sms-si" value="si">
    <label for="sms-si">Sí</label>
    <input type="radio" name="sms" id="sms-no" value="no">
    <label for="sms-no">No</label>
  </div>
  <button type="submit">Confirmar cita</button>
</form>

Así sí: fieldset y legend en cada pregunta

Cada div pasa a ser un fieldset, y cada pregunta, un legend colocado como primer hijo del grupo. El aspecto se mantiene con CSS. El lector de pantalla anuncia la pregunta al entrar en el grupo, y así «Sí» y «No» tienen contexto.

Pruébelo aquí:

Ver el código del ejemplo correcto
<style>
  .grupo { border: 1px solid #767676; padding: 4px 12px 8px; margin: 0 0 12px; }
  .pregunta { font-weight: bold; margin: 4px 0; padding: 0 4px; }
</style>
<form action="#">
  <fieldset class="grupo">
    <legend class="pregunta">¿Es su primera visita a la oficina?</legend>
    <input type="radio" name="primera" id="primera-si" value="si">
    <label for="primera-si">Sí</label>
    <input type="radio" name="primera" id="primera-no" value="no">
    <label for="primera-no">No</label>
  </fieldset>
  <fieldset class="grupo">
    <legend class="pregunta">¿Desea recibir un recordatorio por SMS?</legend>
    <input type="radio" name="sms" id="sms-si" value="si">
    <label for="sms-si">Sí</label>
    <input type="radio" name="sms" id="sms-no" value="no">
    <label for="sms-no">No</label>
  </fieldset>
  <button type="submit">Confirmar cita</button>
</form>

Cómo comprobarlo

Teclado

  1. Entrar en cada grupo con el tabulador y cambiar de opción con las flechas.
  2. Comprobar que el tabulador entra una sola vez en cada grupo de botones de opción. Eso depende de que compartan el atributo name, no del fieldset.

Lector de pantalla (NVDA o VoiceOver)

  1. Llegar con el tabulador a la primera opción de cada grupo.
  2. Comprobar que se anuncia la pregunta (el legend) antes de la etiqueta de la opción.

Debería anunciar: «¿Desea recibir un recordatorio por SMS?, agrupación, Sí, botón de opción, no marcado, 1 de 2»

Herramientas del navegador

  1. Abrir las herramientas de desarrollo (F12), pestaña Accesibilidad, y seleccionar uno de los botones de opción.
  2. En el árbol de accesibilidad, comprobar que está dentro de un nodo «group» cuyo nombre es el texto del legend.

Validación automática

  1. axe DevTools y Lighthouse no exigen fieldset. Un grupo de botones de opción sin agrupar no da error si cada opción tiene etiqueta.
  2. WAVE muestra los fieldset y legend que ya existen, y eso ayuda a revisar. Pero decidir si un grupo necesita descripción se hace a mano.

Errores frecuentes en auditorías

  • Preguntas de «Sí / No» o escalas de valoración maquetadas con div y p, sin fieldset ni legend.
  • Un fieldset con la pregunta dentro de un h3 o un p, y sin legend. El grupo se queda sin nombre.
  • Quitar el fieldset para eliminar el borde que pone el navegador, en lugar de cambiar su estilo con CSS.
  • Anidar fieldset sin necesidad (uno para todo el formulario y otro para cada campo). Los anuncios se hacen más largos.
Ver el texto completo del W3C (traducción al español)

Esta es una traducción no oficial al español de la técnica H71 de Techniques for WCAG 2.2, del W3C. Puede contener errores. El único documento oficial y normativo es la versión original en inglés, publicada en el sitio web del W3C.

Aplicabilidad

HTML

Descripción

El objetivo de esta técnica es proporcionar una agrupación semántica a los controles de formulario relacionados. Esto permite a los usuarios comprender la relación entre los controles e interactuar con el formulario con más rapidez y eficacia.

Los controles de formulario pueden agruparse encerrándolos dentro del elemento fieldset. Todos los controles dentro de un fieldset dado quedan así relacionados. El primer elemento dentro del fieldset debe ser un elemento legend, que proporciona una etiqueta o descripción para el grupo. Los autores deben evitar anidar elementos fieldset innecesariamente, ya que puede generar confusión.

Agrupar los controles es especialmente importante en el caso de los botones de opción y las casillas de verificación relacionados. Un conjunto de botones de opción o de casillas de verificación está relacionado cuando todos envían valores para un mismo campo con nombre. Funcionan de la misma manera que las listas de selección, permitiendo al usuario elegir entre un conjunto de opciones, con la diferencia de que las listas de selección son un único control, mientras que los botones de opción y las casillas de verificación son varios controles. La etiqueta individual asociada a cada botón de opción o casilla de verificación puede no transmitir por completo el contexto descriptivo del grupo. En esta situación es esencial agruparlos semánticamente para facilitar que se traten como un único control, así como para proporcionar una descripción adicional a nivel de grupo. A menudo, los agentes de usuario presentan el valor del legend antes de la etiqueta de cada control para ofrecer esta descripción y, además, para recordar a los usuarios que forman parte del mismo grupo.

También puede ser útil agrupar otros conjuntos de controles menos estrechamente relacionados que los botones de opción y las casillas de verificación. Por ejemplo, varios campos que recogen la dirección de un usuario podrían agruparse con un legend «Dirección», proporcionando así una descripción a nivel de grupo para esos controles. Como regla general, puede decirse que cuando un grupo de controles dentro de un formulario más amplio necesita un encabezado adicional que ofrezca una descripción específica de ese grupo concreto, el uso de los elementos fieldset y legend es apropiado.

Sin embargo, cuando un grupo de botones de opción o casillas de verificación relacionados (incluso con valores para un mismo campo con nombre) incluye instrucciones claras y opciones bien diferenciadas (es decir, cuando la etiqueta individual asociada a cada control concreto proporciona una descripción suficiente), no es necesario usar los elementos fieldset y legend. En este caso, H44 es suficiente.

A veces los autores evitan utilizar el elemento fieldset por su presentación predeterminada en el navegador, que dibuja un borde alrededor de los controles agrupados. Esta agrupación visual también es útil, y los autores deberían considerar seriamente conservarla (o alguna forma de agrupación visual). El efecto visual puede modificarse con CSS sobrescribiendo la propiedad border del fieldset y la propiedad position del legend.

Ejemplos

Un examen tipo test

Este ejemplo muestra una pregunta de examen con una cuestión y cinco respuestas posibles. Cada respuesta se representa con un botón de opción (input type="radio"). Los botones de opción están contenidos dentro de un fieldset. La pregunta del examen se marca con el elemento legend. Cada campo tiene el mismo atributo name, lo que indica que estos botones de opción están relacionados y deben agruparse como se muestra. Observe también que, aunque los atributos name tienen el mismo valor, los valores de los atributos id deben ser únicos.

<fieldset>
  <legend>The play <cite>Hamlet</cite> was written by:</legend>
  <div>
    <input checked="checked" id="shakesp" name="hamlet" type="radio" value="a">
    <label for="shakesp">William Shakespeare</label>
  </div>
  <div>
    <input id="austen" name="hamlet" type="radio" value="b">
    <label for="austen">Jane Austen</label>
  </div>
  <div>    
    <input id="gbshaw" name="hamlet" type="radio" value="c">
    <label for="gbshaw">George Bernard Shaw</label>
  </div>
  <div>
    <input id="woolf" name="hamlet" type="radio" value="d">
    <label for="woolf">Virginia Woolf</label>
  </div>
  <div>
    <input id="dickens" name="hamlet" type="radio" value="e">
    <label for="dickens">Charles Dickens</label>
  </div>
</fieldset>

Un conjunto de casillas de verificación

La página de perfil de usuario de un sitio web permite a los usuarios indicar sus intereses marcando varias casillas de verificación. Cada casilla de verificación (input type="checkbox") tiene un label. Las casillas de verificación están contenidas dentro de un fieldset, y el elemento legend contiene la indicación para todo el grupo de casillas.

<fieldset>
  <legend>I am interested in the following (check all that apply):</legend>
  <div>
    <input id="photo" name="interests" type="checkbox" value="ph">
    <label for="photo">Photography</label>
  </div>
  <div>    
    <input checked="checked" id="watercol" name="interests" type="checkbox" value="wa">
    <label for="watercol">Watercolor</label>
  </div>
  <div>  
    <input checked="checked" id="acrylic" name="interests" type="checkbox" value="ac">
    <label for="acrylic">Acrylic</label>
  </div>
</fieldset>

Controles relacionados lógicamente

En este ejemplo, los campos de formulario de la dirección de residencia y de la dirección postal se distinguen por el valor del legend de cada agrupación fieldset.

<form action="/adduser" method="post">
  <fieldset>
    <legend>Your Residential Address</legend>
    <div>
      <label for="raddress">Address:</label>
      <input autocomplete="street-address" id="raddress" name="raddress" type="text">
    </div>
    <div>
      <label for="rzip">Postal/Zip Code:</label>
      <input autocomplete="postal-code" id="rzip" name="rzip" type="text">
    </div>    
  </fieldset>
  <fieldset>
    <legend>Your Postal Address</legend>
    <div>    
      <label for="paddress">Address:</label>
      <input autocomplete="street-address" id="paddress" name="paddress" type="text">
    </div>
    <div>      
      <label for="pzip">Postal/Zip Code:</label>
      <input autocomplete="postal-code" id="pzip" name="pzip" type="text">
    </div>    
  </fieldset>
</form>

Pruebas

Procedimiento

Para los grupos de controles relacionados en los que las etiquetas individuales de cada control no proporcionan una descripción suficiente y se necesita una descripción adicional a nivel de grupo:

  1. Comprobar que el grupo de elementos input o select relacionados lógicamente está contenido dentro de elementos fieldset.
  2. Comprobar que cada fieldset tiene un elemento legend que es el primer hijo del fieldset e incluye una descripción de ese grupo.

Resultados esperados

  • Todas las comprobaciones son verdaderas.

Recursos

Cómo lo comprobamos en ADDAW

En cada auditoría de ADDAW revisamos esta técnica página a página y le entregamos los errores con capturas y la forma de corregirlos.

Solicitar una auditoría

Basado en la técnica H71 del W3C (WCAG 2.2). Explicación y ejemplos: ADDAW. Traducción no oficial del texto del W3C © W3C, licencia de documentos del W3C. ¿Ha visto un error? Escríbanos.