Compila un componente de selección múltiple

Una descripción general fundamental de cómo compilar un componente de selección múltiple responsivo, adaptable y accesible para ordenar y filtrar las experiencias del usuario.

En esta publicación, quiero compartir ideas sobre cómo crear un componente de selección múltiple. Prueba la demostración.

. Demostración

Si prefieres ver un video, aquí tienes una versión de YouTube de esta publicación:

Descripción general

A menudo, los usuarios reciben elementos, a veces, muchos elementos, y en estos en muchos casos, puede ser una buena idea ofrecer una forma de reducir la lista para evitar sobrecarga de opciones. Esta en la entrada de blog explora la IU de filtrado como una forma de reducir las opciones. Para ello, presentar atributos de elementos que los usuarios pueden seleccionar o anular, lo que reduce los resultados lo que reduce la sobrecarga de opciones.

Interacciones

El objetivo es permitir un recorrido rápido de opciones de filtro para todos los usuarios y sus diferentes tipos de entradas. A esto se le brindará una plataforma adaptable y par de componentes. Barra lateral tradicional de casillas de verificación para computadoras, teclados y lectores de pantalla, y un <select multiple> para usuarios táctiles.

Captura de pantalla comparativa que muestra el escritorio claro y oscuro con una barra lateral de
casillas de verificación en comparación con dispositivos móviles iOS y Android con un elemento de selección múltiple.

Esta decisión de usar la selección múltiple integrada para el tacto y no para computadoras de escritorio ahorra trabajo y genera trabajo, pero creo que ofrece experiencias adecuadas con menos deuda de código que crear toda la experiencia responsiva en un solo componente.

Pantalla táctil

El componente táctil ahorra espacio y ayuda con la precisión de la interacción del usuario en móvil. Ahorra espacio al contraer toda la barra lateral de casillas de verificación en una <select> Experiencia táctil integrada. Ayuda a la exactitud de las entradas al mostrar una experiencia de superposición táctil de gran tamaño proporcionada por el sistema.

R
vista previa de captura de pantalla del elemento de selección múltiple en Chrome para Android, iPhone y
iPad El iPad y el iPhone tienen la selección múltiple abierta, y cada uno obtiene un
una experiencia única optimizada para el tamaño de la pantalla.

Teclado y control de juegos

A continuación, se muestra una demostración de cómo usar un <select multiple> desde el teclado.

No se puede aplicar estilo a esta selección múltiple integrada, y solo se ofrece en formato compacto no es adecuado para presentar muchas opciones. Ve cómo realmente no puedes ver la amplitud de opciones en esa pequeña caja? Si bien puedes cambiar el tamaño, aún no se puede usar tanto como una barra lateral de casillas de verificación.

Marca

Ambos componentes estarán incluidos en el mismo elemento <form>. Los resultados de este formulario, ya sean casillas de verificación o una selección múltiple, se observarán y usarán para filtrar la cuadrícula, pero también podrían enviarse a un servidor.

<form>

</form>

Componente de casillas de verificación

Los grupos de casillas de verificación deben estar dentro de <fieldset> elemento y se le dio un <legend> Cuando HTML se estructura de esta manera, los lectores de pantalla y FormData hará lo siguiente: automáticamente la relación de los elementos.

<form>
  <fieldset>
    <legend>New</legend>
    … checkboxes …
  </fieldset>
</form>

Con la agrupación en su lugar, agrega un <label> y una <input type="checkbox"> de cada uno de los filtros. Elegí unir el mío en un <div> para que la propiedad gap de CSS puede espaciarlas de manera uniforme y mantener la alineación cuando las etiquetas tengan varias líneas.

<form>
  <fieldset>
    <legend>New</legend>
    <div>
      <input type="checkbox" id="last 30 days" name="new" value="last 30 days">
      <label for="last 30 days">Last 30 Days</label>
    </div>
    <div>
      <input type="checkbox" id="last 6 months" name="new" value="last 6 months">
      <label for="last 6 months">Last 6 Months</label>
    </div>
   </fieldset>
</form>

Una captura de pantalla con una superposición informativa para la leyenda y
  los elementos del conjunto de campos, muestra el color y el nombre del elemento.

Componente <select multiple>

Una de las funciones que casi no se usa del elemento <select> es la siguiente: multiple Cuando el atributo se usa con un elemento <select>, el usuario puede hacer lo siguiente: elige muchos de la lista. Es como cambiar la interacción de una lista de radio a una lista de casillas de verificación.

<form>
  <select multiple="true" title="Filter results by category">
    …
  </select>
</form>

Para etiquetar y crear grupos dentro de un <select>, usa el elemento <optgroup> y asignarle un atributo y un valor label. Este elemento y este atributo son similares a los elementos <fieldset> y <legend>.

<form>
  <select multiple="true" title="Filter results by category">
    <optgroup label="New">
      …
    </optgroup>
  </select>
</form>

Ahora, agrega <option> elementos para el filtro.

<form>
  <select multiple="true" title="Filter results by category">
    <optgroup label="New">
      <option value="last 30 days">Last 30 Days</option>
      <option value="last 6 months">Last 6 Months</option>
    </optgroup>
  </select>
</form>

Captura de pantalla de la renderización para computadoras de escritorio de un elemento de selección múltiple.

Seguimiento de entradas con contadores para informar a la tecnología de accesibilidad

El estado puesto se utiliza en esta experiencia del usuario para hacer un seguimiento y mantener el recuento de filtros para lectores de pantalla y otras tecnologías de asistencia. El video de YouTube demuestra la función. La integración comienza con HTML y el atributo role="status"

<div role="status" class="sr-only" id="applied-filters"></div>

Este elemento leerá en voz alta los cambios realizados en el contenido. Podemos actualizar el contenidos con CSS contadores a medida que los usuarios interactúan con las casillas de verificación. Para ello, primero necesitamos crear un contador con un nombre en un elemento superior de las entradas y el elemento de estado.

aside {
  counter-reset: filters;
}

De forma predeterminada, el recuento será 0, lo que es genial, nada es :checked. de forma predeterminada en este diseño.

Luego, para incrementar el contador recién creado, nos orientaremos a los elementos secundarios del elemento <aside> que son :checked. A medida que el usuario cambia el estado de las entradas, se contabilizará el contador de filters.

aside :checked {
  counter-increment: filters;
}

CSS ahora conoce el recuento general de la IU de la casilla de verificación y el rol de estado elemento está vacío y en espera de valores. Dado que CSS mantiene el recuento en la memoria, counter() la función permite acceder al valor desde pseudo del elemento:

aside #applied-filters::before {
  content: counter(filters) " filters ";
}

El código HTML del elemento de función de estado ahora anunciará "2 filtros" a una pantalla de lectura. Este es un buen comienzo, pero podemos hacerlo mejor, por ejemplo, compartir el recuento de resultados que actualizaron los filtros. Lo haremos desde JavaScript, ya que es fuera de lo que pueden hacer los contadores.

Captura de pantalla del lector de pantalla de macOS que anuncia la cantidad de filtros activos.

Emoción durante el período de prueba

El algoritmo de contadores funcionaba bien con CSS nesting-1, ya que pude colocar todos los lógica en un bloque. Se siente portátil y centralizada para leer y actualizar.

aside {
  counter-reset: filters;

  & :checked {
    counter-increment: filters;
  }

  & #applied-filters::before {
    content: counter(filters) " filters ";
  }
}

Diseños

En esta sección, se describen los diseños entre los dos componentes. La mayoría de las los estilos de diseño son para el componente de la casilla de verificación de escritorio.

El formulario

Para optimizar la legibilidad y capacidad de lectura rápida para los usuarios, se le otorga al formulario de 30 caracteres, lo que establece un ancho de línea óptico para cada etiqueta de filtro. El formulario usa un diseño de cuadrícula y la propiedad gap para espaciar los conjuntos de campos específicos.

form {
  display: grid;
  gap: 2ch;
  max-inline-size: 30ch;
}

El elemento <select>

La lista de etiquetas y casillas de verificación ocupa demasiado espacio en los dispositivos móviles. Por lo tanto, el diseño verifica el dispositivo apuntador principal del usuario para cambiarlo. la experiencia táctil.

@media (pointer: coarse) {
  select[multiple] {
    display: block;
  }
}

Un valor de coarse indica que el usuario no podrá interactuar con con gran precisión a través del dispositivo de entrada principal. En una dispositivo móvil, el valor del puntero suele ser coarse, como interacción principal es táctil. En un dispositivo de escritorio, el valor del puntero suele ser fine, ya que es común. tener conectado un mouse u otro dispositivo de entrada de alta precisión.

Los conjuntos de campos

El estilo y el diseño predeterminados de una <fieldset> con un <legend> son únicos:

Captura de pantalla de los estilos predeterminados de un conjunto de campos y una leyenda.

Por lo general, para espaciar los elementos secundarios, usaría la propiedad gap, pero la propiedad El posicionamiento de <legend> dificulta la creación de un conjunto espaciado uniformemente. de niños. En lugar de gap, el hermano adyacente selector y margin-block-start.

fieldset {
  padding: 2ch;

  & > div + div {
    margin-block-start: 2ch;
  }
}

De esta forma, se evita que <legend> tenga su espacio ajustado solo al <div> niños.

Captura de pantalla que muestra el espaciado del margen entre las entradas, pero no la leyenda.

La etiqueta de filtro y la casilla de verificación

Como elemento secundario directo de un <fieldset> y dentro del ancho máximo del formulario 30ch, el texto de la etiqueta puede ajustarse si es demasiado largo. Ajustar el texto es genial, pero la desalineación entre el texto y la casilla de verificación no lo es. Flexbox es ideal para esto.

fieldset > div {
  display: flex;
  gap: 2ch;
  align-items: baseline;
}
Captura de pantalla que muestra cómo se alinea la marca de verificación con
    la primera línea de texto en un escenario de ajuste de varias líneas.
Juega más en este CodePen

La cuadrícula animada

La animación de diseño se realiza con Isotope. R de alto rendimiento y potente para ordenar y filtrar de forma interactiva.

JavaScript

Además de ayudar a organizar una cuadrícula animada e interactiva, JavaScript se usa para pulir algunas asperezas.

Normalización de las entradas del usuario

Este diseño tiene una forma con dos formas diferentes de proporcionar información, y no debes serializa el igual. Sin embargo, con algo de JavaScript podemos normalizar los datos.

Captura de pantalla de la consola de JavaScript de Herramientas para desarrolladores, en la que
  muestra el objetivo: resultados normalizados de datos.

Elegí alinear la estructura de datos del elemento <select> con las casillas de verificación agrupadas en la nube. Para ello, una input el objeto de escucha de eventos se agrega al elemento <select>, y en ese momento se selectedOptions de que estén asignados.

document.querySelector('select').addEventListener('input', event => {
  // make selectedOptions iterable then reduce a new array object
  let selectData = Array.from(event.target.selectedOptions).reduce((data, opt) => {
    // parent optgroup label and option value are added to the reduce aggregator
    data.push([opt.parentElement.label.toLowerCase(), opt.value])
    return data
  }, [])
})

Ahora, es seguro enviar el formulario o, en el caso de esta demostración, indicar a Isotope. sobre qué filtrar.

Cómo finalizar el elemento de rol de estado

El elemento solo cuenta y anuncia el recuento de filtros según la casilla de verificación. interacción, pero sentí que era una buena idea compartir además la cantidad de resultados y garantizar que también se cuenten las opciones del elemento <select>.

Elección del elemento <select> reflejada en counter()

En la sección de normalización de datos, ya se creó un objeto de escucha en la entrada. En al final de esta función la cantidad de filtros elegidos y la cantidad de resultados de esos filtros. Los valores se pueden pasar al elemento de rol de estado de esta forma.

let statusRoleElement = document.querySelector('#applied-filters')
statusRoleElement.style.counterSet = selectData.length

Resultados reflejados en el elemento role="status"

:checked proporciona una forma integrada de pasar la cantidad de filtros elegidos a el elemento de rol de estado, pero carece de visibilidad del número filtrado de resultados. JavaScript puede observar la interacción con las casillas de verificación y, después de filtrar el cuadrícula, agrega textContent como lo hizo el elemento <select>.

document
  .querySelector('aside form')
  .addEventListener('input', e => {
    // isotope demo code
    let filterResults = IsotopeGrid.getFilteredItemElements().length
    document.querySelector('#applied-filters').textContent = `giving ${filterResults} results`
})

En conjunto, este trabajo completa el anuncio de “2 filtros que dan 25 resultados”.

Captura de pantalla del lector de pantalla de macOS que anuncia los resultados.

Ahora, nuestra excelente experiencia con la tecnología de asistencia se entregará a todos los a los usuarios, cómo interactúan con él.

Conclusión

Ahora que sabes cómo lo hice, ¿cómo lo harías?‽ 🙂

Diversifiquemos nuestros enfoques y aprendamos todas las formas de desarrollar en la Web. Crear una demostración, twittearme vínculos y la agregaré. a la sección de remixes de la comunidad.

Remixes de la comunidad

Aún no hay nada para ver aquí.