Addaw, ir a inicio Donar

Técnica Scripts de cliente WCAG 2.2

SCR27Reordenar bloques de la página con opciones de menú, no solo arrastrando

Nombre oficial en el W3C: Reordenar secciones de la página mediante el Document Object Model

En pocas palabras

Si una página permite cambiar el orden de sus bloques arrastrándolos con el ratón, debe ofrecer también opciones como «Subir» y «Bajar» en cada bloque. Esas opciones funcionan con teclado. Además, el script debe cambiar el orden real en el código, no solo la posición en pantalla.

Por qué es importante

Arrastrar y soltar exige un ratón o un dedo con buen control. Quien usa solo el teclado, un lector de pantalla o un pulsador no puede arrastrar.

Por ejemplo, en una intranet con módulos de «Agenda», «Noticias» y «Avisos», esas personas no podrían personalizar su panel. Y si el cambio es solo visual, el orden de lectura y de tabulación ya no coincide con lo que se ve.

Cómo se hace

  1. Añada a cada bloque que se puede mover un pequeño menú con opciones como «Subir» y «Bajar». Si la rejilla tiene columnas, añada también «Izquierda» y «Derecha».
  2. Use botones o enlaces para esas opciones y lance el script desde el evento click.
  3. Coloque ese menú dentro del propio bloque en el código, junto a lo que mueve.
  4. Mueva el bloque en el DOM (la estructura de la página que el navegador crea a partir del HTML), por ejemplo con insertBefore. No lo recoloque solo con CSS.
  5. Después de moverlo, devuelva el foco a la opción pulsada. Así la persona puede seguir moviéndolo sin perderse.
  6. Dé a cada opción un nombre claro, como «Subir el bloque Noticias».

Cómo comprobarlo

  1. Localice los bloques que se pueden arrastrar.
  2. Compruebe que cada uno tiene opciones para moverlo que se alcanzan con Tab y se activan con Intro.
  3. Mueva un bloque con el teclado. El foco debe seguir en la opción usada.
  4. Recorra la página con Tab o con el lector de pantalla. El orden debe coincidir con el nuevo orden en pantalla.
  5. En las herramientas del navegador (F12), compruebe que el bloque ha cambiado de sitio en el código.

Ejemplo

Cada módulo de una lista lleva un botón «Subir» que lo mueve de verdad en el código.

<li class="modulo">
  <h2>Noticias</h2>
  <button type="button" class="subir">Subir el bloque Noticias</button>
</li>
<script>
document.querySelectorAll('.subir').forEach(function (boton) {
  boton.addEventListener('click', function () {
    var modulo = boton.closest('.modulo');
    var anterior = modulo.previousElementSibling;
    if (anterior) modulo.parentNode.insertBefore(modulo, anterior);
    boton.focus(); // el foco sigue en el botón pulsado
  });
});
</script>
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 SCR27 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, scripts

Descripción

El objetivo de esta técnica es proporcionar un mecanismo para reordenar componentes que sea a la vez muy usable y accesible. Los dos mecanismos más habituales para reordenar son enviar a los usuarios a una página de configuración en la que pueden numerar los componentes, o permitirles arrastrar y soltar los componentes hasta la posición deseada. El método de arrastrar y soltar es mucho más usable, ya que permite al usuario colocar los elementos en su sitio, de uno en uno, y hacerse una idea del resultado. Por desgracia, arrastrar y soltar depende del uso del ratón. Esta técnica permite a los usuarios interactuar con un menú situado en los componentes para reordenarlos en su sitio de forma independiente del dispositivo. Puede usarse en lugar de la funcionalidad de reordenación mediante arrastrar y soltar, o junto con ella.

El menú es una lista de enlaces que usa el evento onclick, independiente del dispositivo, para desencadenar los scripts que reordenan el contenido. El contenido se reordena en el Document Object Model (DOM), no solo visualmente, de modo que quede en el orden correcto para todos los dispositivos.

Ejemplos

Este ejemplo reordena hacia arriba y hacia abajo. Este enfoque también puede usarse para una reordenación bidimensional añadiendo las opciones izquierda y derecha.

Los componentes de este ejemplo son elementos de una lista sin ordenar. Las listas sin ordenar son un modelo semántico muy adecuado para conjuntos de elementos similares, como estos componentes. El enfoque del menú también puede usarse para otros tipos de agrupaciones.

Los módulos son elementos de lista, y cada módulo, además del contenido en elementos div, contiene un menú representado como una lista anidada.

<ul id="swapper">
    <li id="black">
      <div class="module">
        <div class="module_header">
          <!-- menu link -->
          <a href="#" onclick="ToggleMenu(event);">menu</a>
          <!-- menu -->
          <ul class="menu">
            <li><a href="#" onclick="OnMenuClick(event)" 
              onkeypress="OnMenuKeypress(event);">up</a></li>
            <li><a href="#" onclick="OnMenuClick(event)" 
              onkeypress="OnMenuKeypress(event);">down</a></li>
          </ul>
        </div>
      <div class="module_body">
        Text in the black module
      </div>
    </div>
  </li>
  ...
</ul>

Puesto que ya hemos tratado cómo mostrar y ocultar menús en los ejemplos del árbol sencillo, aquí nos centraremos únicamente en el código que intercambia los módulos. Una vez que armonizamos los eventos y cancelamos la acción predeterminada del enlace, nos ponemos a trabajar. Primero, definimos una serie de variables locales para los elementos con los que vamos a trabajar: el menú, el módulo que se va a reordenar y el enlace del menú (menuLink). Después, tras comprobar la dirección de la reordenación, intentamos obtener el nodo con el que intercambiar. Si lo encontramos, llamamos a swapNode() para intercambiar nuestros dos módulos y a PositionElement() para mover el menú, posicionado de forma absoluta, junto con el módulo, y a continuación devolvemos el foco al elemento del menú que puso todo en marcha.

function MoveNode(evt,dir){
  HarmonizeEvent(evt);
  evt.preventDefault();
  var src = evt.target;
  var menu = src.parentNode.parentNode;
  var module = menu.parentNode.parentNode.parentNode;
  var menuLink = module.getElementsByTagName("a")[0];
  var swap = null;
  switch(dir){
    case 'up': {
      swap = module.previousSibling;
      while (swap && swap.nodeType != 1){
        swap = swap.previousSibling;
      }
        break;
    }
    case 'down': {
      swap = module.nextSibling;
      while (swap && swap.nodeType != 1){
        swap = swap.nextSibling;
      }
        break;
    }
  }
  if (swap && swap.tagName == node.tagName){
    module.swapNode(swap);
    PositionElement(menu,menuLink,false,true);
  }
  src.focus();
}

El CSS para el intercambio de nodos no difiere mucho del de nuestros ejemplos anteriores del árbol, con algunos ajustes de tamaño y color para los módulos y el pequeño menú.

ul#swapper {
  list-item-style:none;
  margin:0px;
  padding:0px;
}
ul#swapper li {
  border:1px solid black;
  height:5em;
  list-style:none;
  margin:1em;
  padding:0;
  width:15em;
}
ul#swapper li a {
  color:white;
  font-size:90%;
  text-decoration:none;
}
ul#swapper li div.module_header {
  padding:0 0.2em;
  text-align:right;
}
ul#swapper li div.module_body {
  padding:0.2em;
}
ul#swapper ul.menu {
  background-color:#eeeeee; 
  border:1px solid gray;
  display:none;
  height:auto;
  list-style:none;
  margin:0;
  padding:0;
  position:absolute;
  text-align:left;
}
ul#swapper ul.menu li {
  border:none;
  font-weight:normal;
  height:auto;
  margin:0;
  text-align:left;
  width:5em;
}
ul#swapper ul.menu li a {
  color:black;
  display:block;
  padding:0 0.1em;
  text-decoration:none;
  width:100%;
}

Pruebas

Procedimiento

  1. Localizar todos los componentes que se pueden reordenar mediante arrastrar y soltar.
  2. Comprobar que existe también un mecanismo para reordenarlos mediante menús construidos con listas de enlaces.
  3. Comprobar que los menús están contenidos dentro de los elementos reordenables en el DOM.
  4. Comprobar que los scripts de reordenación se desencadenan únicamente desde el evento onclick de los enlaces.
  5. Comprobar que los elementos se reordenan en el DOM, no solo visualmente.

Resultados esperados

  • Las comprobaciones n.º 2 a n.º 5 son verdaderas.

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 SCR27 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.