Formularios y Componentes

Los formularios y componentes interactivos son los puntos de fricción más comunes. Implementarlos correctamente es esencial.

Etiquetas y Mensajes de Error

HTML — Formulario accesible
<div class="form-group">
  <label for="nombre">
    Nombre completo
    <span aria-hidden="true">*</span>
    <span class="sr-only">(obligatorio)</span>
  </label>
  <input type="text" id="nombre"
         required autocomplete="name"
         aria-describedby="nombre-error">
  <span id="nombre-error" role="alert" hidden>
    El nombre es obligatorio (mínimo 2 caracteres).
  </span>
</div>

Desplegables (Select)

Siempre preferir el <select> nativo HTML. Es completamente accesible por defecto.

HTML — Select nativo accesible
<label for="pais">País:</label>
<select id="pais" name="pais" required>
  <option value="">Seleccione un país</option>
  <option value="co">Colombia</option>
  <option value="ar">Argentina</option>
</select>

Acordeones

HTML + JS — Acordeón ARIA accesible
<div class="accordion">
  <h3>
    <button aria-expanded="false"
            aria-controls="panel-1"
            id="header-1">
      ¿Cómo creo una cuenta?
      <span aria-hidden="true">+</span>
    </button>
  </h3>
  <div id="panel-1" role="region"
       aria-labelledby="header-1" hidden>
    <p>Para crear una cuenta...</p>
  </div>
</div>

// JavaScript
document.querySelectorAll('.accordion button').forEach(btn => {{
  btn.addEventListener('click', () => {{
    const exp = btn.getAttribute('aria-expanded') === 'true';
    btn.setAttribute('aria-expanded', !exp);
    document.getElementById(btn.getAttribute('aria-controls')).hidden = exp;
  }});
}});

Pestañas / Tabs

HTML — Sistema de pestañas ARIA
<div role="tablist" aria-label="Información del producto">
  <button role="tab" aria-selected="true"
          aria-controls="panel-desc" id="tab-desc">
    Descripción
  </button>
  <button role="tab" aria-selected="false"
          aria-controls="panel-specs" id="tab-specs"
          tabindex="-1">
    Especificaciones
  </button>
</div>

<div role="tabpanel" id="panel-desc"
     aria-labelledby="tab-desc" tabindex="0">
  <p>Contenido...</p>
</div>
<div role="tabpanel" id="panel-specs"
     aria-labelledby="tab-specs" hidden tabindex="0">
  <p>Especificaciones...</p>
</div>