El reto de la entrada de fecha en la Web

La selección de fechas es una de las interacciones más comunes pero frustrantes en la web. Los recolectores de fecha de navegador nativo varían salvajemente a través de plataformas, y el estándar ofrece control de estilo limitado y comportamiento de teclado inconsistente. Construir un selector de fecha personalizado le da control completo sobre la apariencia, el comportamiento y la accesibilidad. Cuando se hace correctamente, se convierte en un componente inclusivo que sirve a los usuarios independientemente de su dispositivo, método de entrada, o tecnología de asistencia.

Un selector de fecha accesible no es sólo sobre el cumplimiento de las directrices de WCAG. Impacta directamente a los usuarios reales: personas que navegan con teclados, quienes confían en lectores de pantalla, personas con discapacidad motor que utilizan dispositivos de conmutación, y cualquiera que se beneficia de cuestiones visuales claras. Las técnicas aquí cubiertas se aplican a cualquier marco JavaScript, pero los ejemplos utilizan vainilla JavaScript para adaptarlos a React, Vue o cualquier otro entorno.

Accesibilidad Fundaciones para los Pickers Fecha

Entender los criterios de éxito de la CMAG

El componente de la práctica [FLT4] asegura que la práctica [FLT4] [FLT4] ] [FLT4]] (SC 2.1.1) exige que toda la funcionalidad sea operable a través de una interfaz de teclado. La función visible (SC 2.4.7) exige un indicador de enfoque claro para que los usuarios sepan qué fecha se selecciona.

HTML semántico como la columna vertebral

Comience con elementos HTML semánticos en lugar de genéricos s. La rejilla del calendario debe utilizar un elemento porque representa semánticamente datos tabulares. Cada célula de fecha debe ser un elemento , que es inherentemente enfocable y activable a través del teclado. Evite usar elementos como objetivos interactivos porque no tienen soporte para teclado nativo y requieren mayor actividad sólida para comunicarte.

Architección del componente de la fecha del Picker

Elementos de interfaz de usuario básico

Un selector de fecha completo necesita estos componentes visuales y funcionales:

  • Un campo de entrada de texto que muestra la fecha seleccionada y activa el popup del calendario
  • Un calendario que contiene un encabezado mes/año, botones de navegación para cambiar meses, y una cuadrícula de días
  • La fecha de hoy es visualmente destacada para la orientación
  • La fecha seleccionada claramente marcada con un estilo distinto
  • Un botón claro o la tecla Escape para desestimar el calendario sin seleccionar

Administración del Estado

Internamente, el selector de fecha debe seguir varias piezas de estado: la fecha actualmente enfocada (que puede diferir de la fecha seleccionada), el mes y el año visible, el valor de fecha seleccionado, y si el calendario emergente está abierto o cerrado. Mantenerlas como variables JavaScript y actualizar los atributos DOM y ARIA en respuesta a cambios estatales. El separar estado de renderización hace que el componente sea más fácil de depurar y extender con características como rangos de fechas o varios meses.

Construcción de la estructura HTML para la accesibilidad

El campo de entrada

El campo de entrada es el punto principal de interacción del usuario. Debe comunicar su propósito y relación con el popup del calendario utilizando atributos ARIA:

Ejemplo de entrada accesible:

<label for="date-picker-input">Departure date</label>
<input type="text"
 id="date-picker-input"
 role="combobox"
 aria-haspopup="dialog"
 aria-expanded="false"
 aria-controls="datepicker-calendar"
 aria-autocomplete="none"
 readonly
 placeholder="MM/DD/YYYY">

El patrón indica que esta entrada controla un popup. El atributo refleja dinámicamente si el calendario es visible. Establecer la entrada como impide la entrada manual de texto al permitir el enfoque del teclado y los eventos de clic. Para las implementaciones que permiten la fijación de fecha directa, añadir lógica de validación y administración del estado.

El diagrama del calendario

El popup del calendario sigue el patrón dialog de las prácticas de autor de ARIA. Debe ser hecho como un hermano al campo de entrada en el DOM, generalmente envuelto en un contenedor que maneja el posicionamiento:

<div id="datepicker-calendar"
 role="dialog"
 aria-modal="true"
 aria-label="Choose a date"
 hidden>
 <div class="calendar-header">
 <button class="prev-month" aria-label="Previous month">&lsaquo;</button>
 <h3 id="calendar-month-year" aria-live="polite">January 2025</h3>
 <button class="next-month" aria-label="Next month">&rsaquo;</button>
 </div>
 <table class="calendar-grid" role="grid" aria-labelledby="calendar-month-year">
 <thead>
 <tr>
 <th scope="col"><abbr title="Sunday">Sun</abbr></th>
 <th scope="col"><abbr title="Monday">Mon</abbr></th>
 <th scope="col"><abbr title="Tuesday">Tue</abbr></th>
 <th scope="col"><abbr title="Wednesday">Wed</abbr></th>
 <th scope="col"><abbr title="Thursday">Thu</abbr></th>
 <th scope="col"><abbr title="Friday">Fri</abbr></th>
 <th scope="col"><abbr title="Saturday">Sat</abbr></th>
 </tr>
 </thead>
 <tbody>
 <!-- Date rows rendered dynamically -->
 </tbody>
 </table>
 <div class="calendar-footer">
 <button class="today-button">Today</button>
 </div>
</div>

La en la tabla proporciona navegación optimizada para los lectores de pantalla dentro de los diseños tabulares. Cada célula de fecha debe ser un elemento con el explícitamente aplicado si se utiliza un elemento no semántico. La región en el encabezado mes/año asegura que los lectores de pantalla anuncian cambios de mes sin interrumpir el usuario.

Implementación de la navegación de teclado

Estrategia de gestión focal

Cuando el calendario se abre, el enfoque se mueve a la fecha seleccionada o a la fecha actual si no existe ninguna selección. Esto sigue el cuadro de diálogo auto-focus]. El calendario debe atrapar el enfoque dentro de sí mismo mientras está abierto, evitando que el usuario se tabbing a elementos detrás del popup. Implementar una trampa de enfoque que se cicle entre los elementos primero y último enfocables dentro del cuadro de diálogo.

Mapping de eventos de teclado

Los cajeros de fecha exigen una interfaz de teclado consistente. El patrón de rejilla de la agenda define los mapas de clave estándar para navegar por el contenido tabular:

  • Las teclas de flecha] mueven el foco un día en la dirección correspondiente. Cuando el enfoque se mueve más allá del mes actual, el calendario cambia automáticamente al mes adyacente.
  • Inicio y Fin] se enfocan en el primer o último día del mes actual.
  • Page Up and Page Down navega hasta el mes anterior o el mes siguiente, preservando el día del mes (al día anterior del mes objetivo si es necesario).
  • Enter o Space selecciona la fecha actualmente enfocada y cierra el calendario.
  • Escape cierra el calendario y vuelve a centrarse en el campo de entrada.
  • Tab mueve el enfoque dentro de los componentes de diálogo (botones de navegación mes, cuadrícula, botón de hoy).

Gestionando tabindex

Usar el patrón probando tabindex dentro de la rejilla de fecha. Sólo un botón de fecha tiene en cualquier momento, mientras que todos los demás botones de fecha tienen . Esto asegura que pulsar Tab una vez entra en la rejilla y presionar Tab vuelve a moverse al siguiente elemento focalizado fuera de la red.

Atributos ARIA para el soporte de lectura de pantalla

Gestión del Estado dinámica ARIA

Los lectores de pantalla confían en los atributos ARIA para comunicar cambios estatales. Actualizar estos atributos en tiempo real a medida que el usuario interactúa con el selector de fecha:

  • ] ] en la entrada: se establece a cuando el calendario se abre, cuando se cierra.
  • ]] en el cuadro de diálogo del calendario: eliminar (] cuando sea visible, añadir () cuando esté oculto.
  • ] elegido por la vía ] en el botón de fecha seleccionado: se establece en en la fecha elegida, en todos los demás. Observe que los botones soportan nativamente un estado presionado, pero es el atributo correcto para los roles de la rejilla.
  • aria-activodescendente en la entrada: apuntar al ID de la actual célula de fecha enfocada.
  • aria-label] en cada botón de fecha: incluir la fecha completa, como "15 de enero de 2025" en lugar de sólo "15".

Anunciando cambios de contexto

Cuando el usuario navega a un nuevo mes, anuncia el mes y el año utilizando una región en vivo. Muchas implementaciones actualizan la en el diálogo o usan una región visualmente oculta . Cuando se selecciona una fecha, anuncian "Enero 15, 2025 seleccionados" para confirmar la acción. Proveer una ] región para confirmar las confirmaciones críticas y

Detalles de la implementación de JavaScript

Iniciación y configuración

Crear una función de clase o fábrica DatePicker que acepte opciones de configuración: el elemento de entrada, formato de fecha, fechas mínimas y máximas, y funciones de callback para la selección de fechas. Inicializar estableciendo oyentes de eventos en la entrada y renderizando el mes calendario inicial:

class AccessibleDatePicker {
 constructor(input, options = {}) {
 this.input = input;
 this.options = Object.assign({
 format: 'MM/DD/YYYY',
 minDate: null,
 maxDate: null,
 onDateSelect: () => {}
 }, options);

 this.selectedDate = null;
 this.focusedDate = null;
 this.currentMonth = new Date().getMonth();
 this.currentYear = new Date().getFullYear();
 this.isOpen = false;

 this.calendar = this.buildCalendarElement();
 this.setupEventListeners();
 }
 // ... methods
}

Rendering the Calendar Grid

La función de renderizado calcula el primer día del mes, el número de días del mes, y los días de seguimiento de los meses anteriores y siguientes para llenar la red. Cada botón de fecha recibe atributos de datos para los componentes de fecha y un con la fecha legible por el ser humano:

renderMonth() {
 const firstDay = new Date(this.currentYear, this.currentMonth, 1).getDay();
 const daysInMonth = new Date(this.currentYear, this.currentMonth + 1, 0).getDate();
 const daysInPrevMonth = new Date(this.currentYear, this.currentMonth, 0).getDate();

 let cells = [];
 // Add trailing days from previous month
 for (let i = firstDay - 1; i >= 0; i--) {
 cells.push(this.createDateButton(daysInPrevMonth - i, this.currentMonth - 1, this.currentYear, true));
 }
 // Add days of current month
 for (let day = 1; day <= daysInMonth; day++) {
 cells.push(this.createDateButton(day, this.currentMonth, this.currentYear));
 }
 // Add leading days of next month
 const remaining = 42 - cells.length; // 6 rows × 7 columns
 for (let day = 1; day <= remaining; day++) {
 cells.push(this.createDateButton(day, this.currentMonth + 1, this.currentYear, true));
 }
 // Render into table body...
}

Delegación de eventos para contenido dinámico

En lugar de adjuntar los oyentes de eventos a cada botón de fecha individualmente, utilice la delegación de eventos en el contenedor de red. Escuchar eventos en el elemento y determinar qué fecha se hizo clic usando . Este enfoque maneja fechas generadas dinámicamente sin escuchar retumbantes y reduce el uso de la memoria. Para eventos de teclado, adjunta un

Fecha de selección Flujo

Cuando un usuario selecciona una fecha, el componente formatea la fecha según el formato configurado, actualiza el valor de entrada, almacena la fecha seleccionada internamente, y llama la llamada . Después de la selección, el calendario cierra y se centra devuelve a la entrada. Actualizar el atributo ] en la celda previamente seleccionada a y en la nueva celda seleccionada a

Visual Styling for Accessibility

Contraste y Independencia de Color

El color nunca debe ser el único indicador de estado. Utilice una combinación de color de fondo, color de texto, frontera y decoración de texto para comunicar estados seleccionados, enfocados y discapacitados. Mantenga una relación de contraste mínima de 3:1 para contenido no texto y 4.5:1 para contenido de texto por WCAG SC 1.4.3 y 1.4.11. Proveer un modo de alto contraste] que utiliza fronteras audaces y en lugar de cambios de color sutiles.

Diseño de indicadores focales

El indicador de enfoque debe ser visible contra todos los elementos circundantes. Use un o con suficiente espesor y contraste. Evite eliminar el esquema de navegador predeterminado sin proporcionar un reemplazo. Un esquema sólido de 3 píxeles con un color que contrasta tanto con el fondo predeterminado como con el fondo estatal seleccionado asegura la visibilidad.

Touch Target Sizing

Cada botón de fecha debe tener un objetivo mínimo de 44x44 píxeles CSS, como recomienda WCAG SC 2.5.8. Esto se aplica a dispositivos móviles, tabletas y usuarios con baja destreza que pueden utilizar el tacto o el estilo de entrada. Asegúrese de los botones de navegación mes y el botón de hoy también cumplir con estas dimensiones mínimas. Si las restricciones del espacio requieren objetivos más pequeños, proporcionar relleno visual o aumentar el área clicable utilizando pseudo-

Pruebas de su fecha de selección para accesibilidad

Pruebas manuales de teclado

Prueba el componente usando sólo un teclado. Tab en la entrada, abre el calendario con Enter o Space, y navega a través de todas las fechas utilizando las teclas de flecha. Verifica que Escape cierra el popup y vuelve a centrarse en la entrada. Confirma que el indicador de enfoque es visible en todo momento y que el orden de enfoque sigue el diseño visual. Prueba con Page Up, Page Down, Home y End teclas para asegurar que realizan el mes y día esperados de navegación.

Testing de lectura de pantalla

Prueba con al menos dos lectores de pantalla. Una combinación de NVDA] (gratis) con Firefox y JAWS con Chrome cubre la mayoría de los usuarios de lectores de pantalla. Verifica que el lector de pantalla anuncia el papel de diálogo, el mes y el año, y la fecha como el usuario navega[LT]

Herramientas de prueba automatizadas

Utilizar herramientas automatizadas como axe DevTools] o Lighthouse para captar problemas comunes de accesibilidad. Estas herramientas pueden identificar atributos ARIA desaparecidos, contraste de color insuficiente y etiquetas perdidas. Sin embargo, las pruebas automatizadas no pueden detectar todos los problemas.

Consideraciones de la integración real mundial

Internacionalización y Localización

Los buscadores de fechas sirven a un público global. Admite múltiples locales utilizando la API para formatear fechas y nombres de mes. Permite la configuración del primer día de la semana (Sunday vs. Lunes) basado en locale. Los encabezados de semana de Render utilizan nombres abreviados que respetan el local. Proporcionar traducciones para etiquetas ARIA como "Mes anterior" y "Elija una fecha".

Optimización táctil y móvil

En dispositivos móviles, coloca el cuadro de diálogo calendario para evitar superponer con el teclado virtual. Considera usar un modal de pantalla completa para el calendario en pantallas pequeñas, con todo el puerto de visualización dedicado a la interfaz de selección de fechas. Implementa gestos de deslizamiento para la navegación mes como un realce progresivo. Prueba en dispositivos móviles reales con entrada de lectores de tacto y pantalla para confirmar que los objetivos táctiles son suficientemente grandes y que las acciones de gesto tienen los inconvenientes accesibles.

Tamaño de rendimiento y de la aglomeración

Un buscador de fecha personalizado no debe cerrar su aplicación. Mantenga el paquete JavaScript bajo 10KB minificado y con un brillo evitando dependencias innecesarias y escribiendo código eficiente. Utilice cierres y funciones de fábrica para evitar la herencia de clase. Lazy-inicializa el calendario DOM sólo cuando el usuario abre primero el picker, en lugar de crearlo en la carga de página. Limpiar los oyentes de eventos y referencias DOM cuando el componente es destruido para evitar las filtraciones de memoria.

Manejo de los casos de borde

Discapacitados y Fechas restringidas

Implementar una función que comprueba las fechas min/max, restricciones de día de semana y reglas de exclusión personalizadas. Las fechas de discapacidad deben recibir y ser excluidas de la navegación del teclado. Visualmente, las fechas deshabilitadas deben usar menor opacidad y evitar efectos de arrastre. Cuando un usuario se registra a través de la red, salte las fechas completamente deshabilitación.

Valores nulos y acciones claras

Soporte despejar la fecha seleccionada proporcionando un botón claro dentro del pie del calendario o permitiendo al usuario volver a hacer clic en la fecha seleccionada. Cuando no se selecciona fecha, el titular de entrada debe comunicar el formato esperado. El calendario debe abrir mostrar el mes actual sin fecha resaltada, pero con enfoque en la fecha de orientación de hoy. Persiste el último mes seleccionado para que si el usuario reabsiente el calendario, vuelva al mes que estaban viendo previamente.

Compatibilidad de navegador y marco

Prueba el selector de fecha a través de Chrome, Firefox, Safari y Edge. Preste atención especial a Safari, que ha tenido históricamente soporte de indicador de enfoque inconsistente. Utilice para proporcionar indicadores de enfoque sólo cuando el usuario navega a través del teclado, evitando esquemas persistentes en interacciones de clic.

Poner todo junto

Un selector de fecha accesible se construye sobre una base de HTML semántico, gestión cuidadosa ARIA y manejo de eventos de teclado robusto. El campo de entrada utiliza semántica combobox para comunicar su relación con el diálogo calendario. La rejilla de fechas sigue el patrón de tabindex de roving para la navegación eficiente del teclado. ARIA atribuye actualización dinámicamente para reflejar el estado actual, los lectores de pantalla reciben anuncios de contexto a través de regiones en vivo, y diseño visual mantiene suficientes indicadores de contraste y enfoque claro.

La medida real del éxito no es cuántos atributos ARIA añades, sino cuán inigualable se siente la experiencia para los usuarios de tecnología de asistencia. Un selector de fecha bien construido debe sentirse tan natural a un usuario de teclado como lo hace a un usuario del ratón. Siguiendo los patrones descritos aquí y probando a fondo con las tecnologías de ayuda real, usted crea un componente que sirve a todos.

La accesibilidad no es una función de rebote o un paso final de pulido. Es una parte integral del proceso de diseño y desarrollo. Cuando se construye con accesibilidad desde el principio, se evitan refactores costosos y se ofrece una mejor experiencia para todos los usuarios.El selector de fechas es sólo un componente, pero los principios que se aplican aquí llevan a través de cada elemento interactivo que construye.