6.6: Paneles de Pestaña
- Page ID
- 152567
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)
( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\id}{\mathrm{id}}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\kernel}{\mathrm{null}\,}\)
\( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\)
\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\)
\( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)Los paneles de pestañas, al igual que los acordeones, se utilizan a menudo para ahorrar espacio y reducir el desplazamiento. Normalmente se componen de una tablista que contiene una serie de pestañas, controlando cada pestaña la visualización de un panel. A medida que se activa cada ficha, se muestra su panel asociado y otros paneles se ocultan. Cuando se selecciona una pestaña, se resalta para indicar qué pestaña y panel están activos.
Funciones, estados y propiedades de WAI-ARIA utilizados en un panel de pestañas
- role="tablist”
- role="tabpanel”
- role="tab”
- aria-oculta= "[verdadero|falso]”
- tabindex = [0 | -1]
- aria-controls= "[id del panel]”
- aria-seleccionado= "[verdadero|falso]”
El siguiente JSFiddle presenta un widget típico del panel de pestañas. Revise el marcado JavaScript y HTML. Pruebe el panel de pestañas presentado bajo la pestaña Resultado con ChromeVox para entender cómo funciona sin que se agreguen características de accesibilidad. Puedes trabajar en JSFiddle haciendo clic en “Editar en JSFiddle”, copiando el código de Accesibilidad/Wai-Aria que se describe a continuación para corregir la accesibilidad del panel de pestañas antes de completar la Actividad 10 en la página que sigue.
En nuestro caso, estamos generando las pestañas para cada hijo <div>definido en el HTML, aunque las pestañas y los paneles de pestañas podrían ser HTML estático. El tablista está conformado por <ul>
<li>elementos a
e hijo. Asignamos
role="tablist”
<ul>a la para eliminar su semántica de lista y reemplazarla con semántica de panel de tabulación.
A continuación, agregamos WAI-ARIA a los paneles, asignamos role="tabpanel”
a cada uno de los <div>elementos originales, los ocultamos por defecto con
aria-hidden="true”
, y finalmente agregamos tabindex="0"
para que el teclado de los paneles se pueda enfocar.
Ahora se definen las pestañas mismas, reemplazando la semántica de elementos de lista con semántica de tabulación agregando role="tab”
a cada uno de los <li>elementos generados. También necesitamos definir qué tabpanel controla qué tabpanel, generando dinámicamente
aria-controls= "[panel_id]”
para cada una de las pestañas.
Cuando se selecciona una pestaña, queremos eliminar la selección de otras pestañas con aria-selected="false”
, y eliminar temporalmente el acceso al teclado asignando tabindex=” -1"
a las pestañas no seleccionadas, de modo que ese tabpanel se convierta en el siguiente en el orden de tabulación, y los usuarios puedan navegar directamente desde la pestaña a el panel sin tener que pasar por las otras pestañas en la tablista.
Así mismo, cuando se selecciona una pestaña asignamos aria-selected="true”
para que los lectores de pantalla anuncien la pestaña seleccionada, agregamos tabindex="0"
como el tabindex errante para que esa pestaña se pueda enfocar.
A medida que cambian las pestañas, oculta todos los paneles con aria-hidden="true”
para que los lectores de pantalla no los vean, luego abre el panel la pestaña actual controla con aria-hidden="false”
para que los lectores de pantalla puedan ver el panel activo. Estos se agregan al final de la función selectTab ()
.
Adición de operabilidad del teclado
W3C describe las prácticas de creación para las interacciones del teclado del panel de pestañas de la siguiente manera
Interacción de teclado para paneles de pestañas
Para la lista de pestañas:
- Pestaña: Cuando el enfoque se mueve a la lista de pestañas, coloca el foco en el elemento
tabulador
activo. Cuando la lista de pestañas contiene el enfoque, mueve el foco al siguiente elemento en la secuencia de pestañas de página fuera de la lista de pestañas, que normalmente es el primer elemento enfoable dentro del panel de pestañas o el propio panel de pestañas. - Cuando el foco está en un elemento de tabulación en una lista de tabulación horizontal:
- Flecha izquierda: mueve el foco a la pestaña anterior. Si el enfoque está en la primera pestaña, mueve el enfoque a la última pestaña. Opcionalmente, activa la pestaña recién enfocada (Ver nota a continuación).
- Flecha derecha: Mueve el foco a la siguiente pestaña. Si el enfoque está en el último elemento de tabulación, mueve el enfoque a la primera pestaña. Opcionalmente, activa la pestaña recién enfocada (Ver nota a continuación).
- Cuando el foco está en una ficha en una tablista con orientación horizontal o vertical:
- Espacio o Entrar: Activa la pestaña si no se activó automáticamente al enfocar.
- Inicio (Opcional): Mueve el enfoque a la primera pestaña
- Fin (Opcional): Mueve el enfoque a la última pestaña.
- Mayús + F10: Si la pestaña tiene un menú emergente asociado, abre el menú.
- Delete (Opcional): Si se permite la eliminación, elimina (cierra) el elemento tabulador actual y su panel de tabulación asociado. Si queda alguna pestaña, establece el enfoque en la pestaña que sigue a la pestaña que se cerró y activa la pestaña recién enfocada. Alternativamente, o además, la función delete está disponible en un menú contextual.
Nota:
- Se recomienda que las pestañas se activen automáticamente cuando reciban el enfoque siempre que sus paneles de pestañas asociados se muestren sin una latencia notable. Esto normalmente requiere que el contenido del panel de pestañas esté precargado. De lo contrario, la activación automática ralentiza el movimiento del enfoque, lo que dificulta significativamente la capacidad de los usuarios para navegar eficientemente por la lista de pestañas Para obtener orientación adicional, consulte 5.4 Decidir cuándo realizar la selección Seguir el enfoque automáticamente.
- Si las pestañas de una lista de tabulaciones están dispuestas verticalmente:
- Flecha abajo funciona como Flecha derecha se describe arriba.
- Flecha arriba funciona como Flecha izquierda se describe arriba.
- Si la lista de pestañas es horizontal, no escucha Flecha abajo o Flecha arriba, por lo que esas teclas pueden proporcionar sus funciones normales de desplazamiento del navegador incluso cuando el foco está dentro de la lista de pestañas.
Como de costumbre, el panel de pestañas necesita ser operable por teclado para ser accesible a los lectores de pantalla. La función OnKeyDown ()
se agrega a las funciones, para agregar navegación de teclas de flecha entre pestañas, y entre pestañas y paneles. La navegación por tabulaciones y las teclas Enter están habilitadas por defecto y no es necesario definirlas aquí.
Luego se agrega la función OnKeyDown
a cada pestaña, referenciada con la función .on ('keydown')
de jQuery, agregada a la definición $tab
de la función init ()
.
Ahora, con el acceso de teclado y WAI-ARIA agregado para definir la semántica del panel de pestañas, debería ser completamente funcional para lectores de pantalla.
Panel de pestañas accesible en acción
Vea el siguiente video que muestra ChromeVox interactuando con un panel de pestañas. La tecla Tab se utiliza para navegar al panel de pestañas y a la primera pestaña. Las teclas de flecha se utilizan para moverse entre pestañas y, cuando se encuentra en una pestaña, la tecla Tab se utiliza para navegar hasta el panel asociado. Mientras está en un panel, Shift + Tab se usa para volver a la tablista. También puede haber flechas Arriba y Abajo habilitadas para moverse entre pestañas y paneles, aunque no las hemos habilitado aquí. Apunta a que el panel de pestañas que actualices en la actividad que viene en la siguiente página opere y se anuncie como el del video.
Video: Panel de Pestañas Accesibles