Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

193
Views
¿Qué etiqueta de aria debo usar para los elementos 'inactivos' en una lista con los que el usuario todavía puede interactuar?

Tengo una lista de datos en una visualización y quiero que sea lo más accesible posible. Hay dos listas una al lado de la otra.

Los elementos de la lista tienen dos estados. Varias filas pueden estar activas o inactivas. Se puede seleccionar una sola fila.

Al seleccionar algo en una lista, se mostrarán los elementos 'relacionados' como activos e inactivos. Vea el ejemplo simplificado a continuación. El usuario seleccionó "A 2", que está vinculado a "B 1" y "B 4", por lo que A2 está aria-selected pero no hay aria-active o aria-inactive , pensé en usar aria-disabled como se demostró: ¿PERO esto no indica que no se puede interactuar? El usuario aún puede hacer clic en el elemento deshabilitado para luego seleccionarlo.

¿Sería mejor hacer múltiples aria-selected y un solo aria-current=true en el único elemento 'seleccionado'? ¿Sería extraño que si el usuario aún no ha hecho una selección y todo está 'activo', todos los elementos serán aria-selected=true ?

 .container { display: grid; grid-template-columns: 200px 200px } .list div { margin: 0.5rem; background: grey; } .list .selected { background: red; } .list .inactive { opacity: 0.3; }
 <div class="container"> <div class="list"> <div role="row">A 1</div> <div role="row" class="selected" aria-selected="true">A 2</div> <div role="row">A 3</div> <div role="row">A 4</div> </div> <div class="list"> <div role="row">B 1</div> <div role="row" class="inactive" aria-disabled="true">B 2</div> <div role="row" class="inactive" aria-disabled="true">B 3</div> <div role="row">B 4</div> </div> </div>

Aclaraciones de comentarios. Así es como se ve la implementación real con un elemento seleccionado: ingrese la descripción de la imagen aquí , es bastante complejo, así que traté de desglosarlo hasta el problema específico.

  1. Al igual que en cada lista, ¿es uno a muchos que se pueden seleccionar a la vez? Solo se puede 'seleccionar' un elemento, como en el ejemplo. Varios elementos están 'resaltados' o 'activos'. Cuando no se selecciona nada, todos están 'activos'.
  2. ¿Cómo se correlacionan las listas entre sí? ¿Cómo se correlacionan con el contenido que pueden estar proporcionando? Los elementos tienen una spline en el medio, que se conectan entre sí y les he dado un role="presentation" . En realidad, hay una línea de tiempo en el medio, y las cosas solo están 'activas' si los elementos en la línea de tiempo comparten el elemento en la otra lista.
  3. Si hay cambios de contenido para reflejar sus relaciones, ¿es posible que deba considerar cosas como la actualización atómica de aria que depende de las correlaciones relevantes de aria, etc.? Estaba considerando esto. Los elementos cambian solo si se desplaza, lo único que cambia de lo contrario es el estado activo/resaltado y seleccionado.

No había considerado una aria-label , creo que podría ser la mejor solución porque el usuario puede hacer clic y seleccionar el elemento inactivo.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Desde el punto de vista de la semántica y la accesibilidad, consideraría separar los controles de la visualización en sí, al menos en términos de marcado. Esto le permitirá usar más elementos de entrada semánticos, como <input type="radio"> , que vienen con sus propios estados que la tecnología de asistencia entiende. Y mantendrá el estado de selección (que es un rasgo de elemento de entrada) separado del estado resaltado (que es un rasgo de visualización).

A continuación, puede vincular esos elementos de entrada a la visualización mediante el atributo aria-controls .

Para indicar el estado de los elementos en la visualización en sí, en lugar de usar roles ARIA, sugeriría usar solo texto.

Un ejemplo básico podría funcionar algo como esto:

 const items = document.querySelectorAll('.item') document.querySelectorAll('input').forEach(input => { input.addEventListener('change', e => { let targets = e.target.dataset.controls.split(' ') items.forEach(item => { let index = targets.indexOf(item.id) if (-1 === index) item.dataset.state = 'inactive' else if (0 === index) item.dataset.state = 'selected' else item.dataset.state = 'highlighted' }) }) })
 body { display: grid; grid-template: auto auto / auto auto; grid-auto-flow: column; } form, figure { display: grid; grid-template: auto/auto auto 1fr; gap: 1ch; } fieldset { display: grid; grid-template: auto/auto auto; } input, label { cursor: pointer; } figure, ul { padding: 0; margin: 0; } ul { list-style: none; } li { margin: 1ch 0 0 1ch; padding: 1ch; } li[data-state="inactive"] { background: #ddd; } li[data-state="selected"] { background: #aaffaa; } li[data-state="highlighted"] { background: #aaaaff; } li[data-state="inactive"] span, li[data-state="highlighted"] span.selected { display: none; } li[data-state="selected"] span, li[data-state="highlighted"] span.highlighted { display: inline; }
 <h2>Controls</h2> <form> <fieldset> <legend>List A</legend> <input id="input-A1" type="radio" name="input" aria-controls="graphic" data-controls="item-A1 item-B2 item-B3" /> <label for="input-A1">A1</label> <input id="input-A2" type="radio" name="input" aria-controls="graphic" data-controls="item-A2 item-B1" /> <label for="input-A2">A2</label> <input id="input-A3" type="radio" name="input" aria-controls="graphic" data-controls="item-A3 item-B2 item-B3 item-B4" /> <label for="input-A3">A3</label> <input id="input-A4" type="radio" name="input" aria-controls="graphic" data-controls="item-A4 item-B2" /> <label for="input-A4">A4</label> </fieldset> <fieldset> <legend>List B</legend> <input id="input-B1" type="radio" name="input" aria-controls="graphic" data-controls="item-B1 item-A2 item-A3 item-A4" /> <label for="input-B1">B1</label> <input id="input-B2" type="radio" name="input" aria-controls="graphic" data-controls="item-B2 item-A2 item-B3" /> <label for="input-B2">B2</label> <input id="input-B3" type="radio" name="input" aria-controls="graphic" data-controls="item-B3 item-A1 item-A4" /> <label for="input-B3">B3</label> <input id="input-B4" type="radio" name="input" aria-controls="graphic" data-controls="item-B4 item-A2" /> <label for="input-B4">B4</label> </fieldset> </form> <h2>Visualization</h2> <figure id="graphic" aria-live="polite"> <ul aria-label="List A"> <li class="item" id="item-A1" data-state="inactive">A1<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li> <li class="item" id="item-A2" data-state="inactive">A2<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li> <li class="item" id="item-A3" data-state="inactive">A3<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li> <li class="item" id="item-A4" data-state="inactive">A4<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li> </ul> <ul aria-label="List B"> <li class="item" id="item-B1" data-state="inactive">B1<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li> <li class="item" id="item-B2" data-state="inactive">B2<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li> <li class="item" id="item-B3" data-state="inactive">B3<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li> <li class="item" id="item-B4" data-state="inactive">B4<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li> </ul> </figure>

Pero probablemente desee que la visualización sea directamente manipulable haciendo clic en los elementos mismos. Si es así, podría mantener la misma estructura que el primer ejemplo, pero ocultar visualmente los controles y el texto accesibles, y activar los controles cada vez que un usuario haga clic en un elemento de la visualización.

Nuevamente, esto todavía tiene los controles de formulario que son responsables de controlar el estado; simplemente están ocultos visualmente:

 const items = document.querySelectorAll('.item') document.querySelectorAll('input').forEach(input => { input.addEventListener('change', e => { let targets = e.target.dataset.controls.split(' ') items.forEach(item => { let index = targets.indexOf(item.id) if (-1 === index) item.dataset.state = 'inactive' else if (0 === index) item.dataset.state = 'selected' else item.dataset.state = 'highlighted' }) }) }) items.forEach(item => { item.addEventListener('click', e => { let inputId = 'input-' + e.target.id.split('-')[1] document.getElementById(inputId).click() }) })
 .sr-only { border: 0; clip: rect(1px, 1px, 1px, 1px); -webkit-clip-path: inset(50%); clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; white-space: nowrap; } figure { display: grid; grid-template: auto/auto auto 1fr; gap: 1ch; } figure, ul { padding: 0; margin: 0; } ul { list-style: none; } li { margin: 1ch 0 0 1ch; padding: 1ch; cursor: pointer; } li:hover { opacity: 0.6; } li[data-state="inactive"] { background: #ddd; } li[data-state="selected"] { background: #aaffaa; } li[data-state="highlighted"] { background: #aaaaff; } li[data-state="inactive"] span, li[data-state="highlighted"] span.selected { display: none; } li[data-state="selected"] span, li[data-state="highlighted"] span.highlighted { display: inline; }
 <div class="sr-only"> <h2>Controls</h2> <form> <fieldset> <legend>List A</legend> <input id="input-A1" type="radio" name="input" aria-controls="graphic" data-controls="item-A1 item-B2 item-B3"/> <label for="input-A1">A1</label> <input id="input-A2" type="radio" name="input" aria-controls="graphic" data-controls="item-A2 item-B1"/> <label for="input-A2">A2</label> <input id="input-A3" type="radio" name="input" aria-controls="graphic" data-controls="item-A3 item-B2 item-B3 item-B4"/> <label for="input-A3">A3</label> <input id="input-A4" type="radio" name="input" aria-controls="graphic" data-controls="item-A4 item-B2"/> <label for="input-A4">A4</label> </fieldset> <fieldset> <legend>List B</legend> <input id="input-B1" type="radio" name="input" aria-controls="graphic" data-controls="item-B1 item-A2 item-A3 item-A4"/> <label for="input-B1">B1</label> <input id="input-B2" type="radio" name="input" aria-controls="graphic" data-controls="item-B2 item-A2 item-B3"/> <label for="input-B2">B2</label> <input id="input-B3" type="radio" name="input" aria-controls="graphic" data-controls="item-B3 item-A1 item-A4"/> <label for="input-B3">B3</label> <input id="input-B4" type="radio" name="input" aria-controls="graphic" data-controls="item-B4 item-A2"/> <label for="input-B4">B4</label> </fieldset> </form> </div> <h2 class="sr-only">Visualization</h2> <figure id="graphic" aria-live="polite"> <ul aria-label="List A"> <li class="item" id="item-A1" data-state="inactive">A1<span class="sr-only selected">, selected</span><span class="sr-only highlighted">, highlighted</span></li> <li class="item" id="item-A2" data-state="inactive">A2<span class="sr-only selected">, selected</span><span class="sr-only highlighted">, highlighted</span></li> <li class="item" id="item-A3" data-state="inactive">A3<span class="sr-only selected">, selected</span><span class="sr-only highlighted">, highlighted</span></li> <li class="item" id="item-A4" data-state="inactive">A4<span class="sr-only selected">, selected</span><span class="sr-only highlighted">, highlighted</span></li> </ul> <ul aria-label="List B"> <li class="item" id="item-B1" data-state="inactive">B1<span class="sr-only selected">, selected</span><span class="sr-only highlighted">, highlighted</span></li> <li class="item" id="item-B2" data-state="inactive">B2<span class="sr-only selected">, selected</span><span class="sr-only highlighted">, highlighted</span></li> <li class="item" id="item-B3" data-state="inactive">B3<span class="sr-only selected">, selected</span><span class="sr-only highlighted">, highlighted</span></li> <li class="item" id="item-B4" data-state="inactive">B4<span class="sr-only selected">, selected</span><span class="sr-only highlighted">, highlighted</span></li> </ul> </figure>

over 4 years ago · Santiago Trujillo Report

0

Creo que la solución a su problema es usar el índice de pestañas. Puede leer más sobre esto aquí: https://developers.google.com/web/fundamentals/accessibility/focus/using-tabindex

En resumen, puede usar tabindex="-1" para eliminar un elemento del orden de tabulación natural, pero aún se puede enfocar el elemento llamando a su método focus().

Editar: probablemente me perdí mencionar por qué podría ser necesario configurar el índice de tabulación. Para la accesibilidad, al usar listas interactivas, se debe considerar el hecho de que la interfaz de usuario también debe ser navegable con el teclado. Para esta configuración, ayudará el índice de tabulación para elementos activos e inactivos.

Sin embargo, probablemente debería haber mencionado el uso de aria-live='polite' ( https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions ) para regiones con contenido dinámico. Esto permitirá que el lector de pantalla observe los cambios en esa región y los anuncie. Además, puede usar [role='list'] o [role='group'] para proporcionar contexto adicional a los lectores de pantalla sobre la lista.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!