Accy

Informe de ejemplo — así se ve un análisis de Accy

Esto es un análisis real de una tienda de ejemplo con los fallos que cometen los temas de verdad. Tu informe tendrá esta misma forma.

Sin registro. Analizamos una página pública y no guardamos tus datos.

Analizado el 15 de septiembre de 2026 a las 20:55

tienda-de-ejemplo.es

16/ 100

Riesgo crítico

  • 22 reglas incumplidas
  • 9 reglas superadas
  • 5 para revisar a mano

29 incidencias en total, repartidas así

  • 6 Crítico
  • 15 Grave
  • 7 Moderado
  • 1 Leve
Plataforma detectada
Shopify · Dawn
No hemos encontrado declaración de accesibilidad
Generar una gratis →

Qué hay que arreglar

  1. Campos de formulario sin etiqueta

    Crítico

    1 vez en esta página · WCAG 1.3.1, 3.3.2, 4.1.2 (A) · EN 301 549 9.1.3.1, 9.3.3.2, 9.4.1.2

    Hay campos de formulario sin nombre accesible: ni <label>, ni aria-label, ni aria-labelledby.

    Por qué importa

    Un campo sin etiqueta se anuncia como «cuadro de texto» y nada más. En un buscador es molesto; en la dirección de envío del checkout hace que la compra sea imposible de completar sin adivinar.

    Un campo confuso en el checkout es un carrito abandonado. Esto no es solo cumplimiento: es conversión.

    Cómo se arregla

    Asocia un <label> con el atributo for al id del campo, o envuelve el campo dentro del label. El placeholder no cuenta: desaparece al escribir y muchos lectores de pantalla no lo anuncian.

    En tu plataforma · Shopify

    Los formularios del checkout de Shopify ya vienen etiquetados. Revisa los que has añadido tú: newsletter en el pie, buscador del cabecero y formularios de apps de terceros.

    Así está
    <input type="email" name="email">
    Así debería estar
    <label for="email">Correo electrónico</label>
    <input type="email" id="email" name="email" autocomplete="email">
    
    <!-- O envolviendo -->
    <label>Código postal
      <input type="text" name="cp" autocomplete="postal-code">
    </label>
    Ver dónde ocurre
    • body.template-index > div.newsletter:nth-of-type(5) > form > input:nth-of-type(1)
      <input type="email" name="email">
  2. Botones sin nombre

    Crítico

    1 vez en esta página · WCAG 4.1.2 (A) · EN 301 549 9.4.1.2

    Hay botones sin texto visible ni nombre accesible.

    Por qué importa

    Suele pasar con los botones de solo icono: la X de cerrar, la lupa de buscar, el carrito del cabecero. Un lector de pantalla los anuncia como «botón» y la persona tiene que activarlos para descubrir qué hacen.

    Cómo se arregla

    Si el botón tiene texto visible, ya está. Si es solo un icono, añade aria-label con la acción y marca el icono con aria-hidden="true".

    En tu plataforma · Shopify

    En el tema Dawn y derivados, los botones de icono del cabecero se editan en sections/header.liquid.

    Así está
    <button><svg>…</svg></button>
    Así debería estar
    <button aria-label="Cerrar el aviso">
      <svg aria-hidden="true">…</svg>
    </button>
    Ver dónde ocurre
    • body.template-index > div.header:nth-of-type(1) > button.cart-toggle

      Solo hay un icono, sin título ni etiqueta.

      <button class="cart-toggle"><svg viewBox="0 0 24 24"><path d="M7 4h14l-2 9H8z" /></svg></button>
  3. Contraste de color insuficiente

    Grave

    4 veces en esta página · WCAG 1.4.3 (AA) · EN 301 549 9.1.4.3

    Hay texto de 18px con un contraste de 2.35:1 sobre su fondo, cuando la norma pide 4.5:1.

    Por qué importa

    Es la barrera más extendida y la que más gente afecta: cualquiera con vista cansada, con el móvil al sol o con una pantalla mala. No hace falta tener una discapacidad reconocida para no poder leer un gris claro sobre blanco.

    Los textos que suelen fallar son precisamente los que venden: precios tachados, gastos de envío, mensajes de stock.

    Cómo se arregla

    Oscurece el texto o aclara el fondo hasta alcanzar la proporción exigida. El texto normal necesita 4.5:1; a partir de 24 px (o 18.66 px en negrita) basta con 3:1. Los grises de tipo #999 sobre blanco casi nunca pasan.

    En tu plataforma · Shopify

    En el editor de temas, Configuración › Colores permite cambiar los esquemas de color del tema sin tocar código.

    Así está
    /* 2.85:1 — no cumple */
    .precio-antiguo { color: #999999; background: #ffffff; }
    Así debería estar
    /* 4.83:1 — cumple */
    .precio-antiguo { color: #717171; background: #ffffff; }
    Ver dónde ocurre
    • body.template-index > div.hero:nth-of-type(2) > p.hero-sub
      <p class="hero-sub">Fabricada en España con algodón orgánico certificado.</p>
    • body.template-index > div.grid:nth-of-type(3) > div.card:nth-of-type(1) > span.price-old:nth-of-type(1)
      <span class="price-old">29,00 €</span>
    • body.template-index > div.grid:nth-of-type(3) > div.card:nth-of-type(1) > a:nth-of-type(2)
      <a href="/products/camiseta-arena">Leer más</a>
    • body.template-index > div.footer:nth-of-type(6) > p.legal
      <p class="legal">© 2026 Tienda de ejemplo. Todos los derechos reservados.</p>
  4. Falta la declaración de accesibilidad

    Grave

    1 vez en esta página · EN 301 549 Annex V

    No hemos encontrado ningún enlace a una declaración de accesibilidad en la página.

    Por qué importa

    La Ley 11/2023, que traspone la Directiva europea de accesibilidad, obliga a informar de cómo cumple el servicio los requisitos de accesibilidad. Es la parte que una autoridad de vigilancia puede comprobar sin abrir una sola herramienta técnica: mira el pie de página y, si no está, ya tiene un incumplimiento documentado.

    Es el incumplimiento más barato de corregir y el más fácil de detectar desde fuera. Arreglarlo es una tarde; que te lo detecten es un expediente.

    Cómo se arregla

    Publica una página de accesibilidad y enlázala desde el pie, junto al aviso legal y la política de privacidad. Debe indicar el nivel de conformidad que declaras, qué partes sabes que aún no cumplen, la fecha de la última revisión y una vía de contacto para reportar barreras.

    En tu plataforma · Shopify

    Crea la página en Tienda online › Páginas y añádela al menú del pie en Navegación.

    Así está
    <footer>
      <a href="/aviso-legal">Aviso legal</a>
      <a href="/privacidad">Privacidad</a>
    </footer>
    Así debería estar
    <footer>
      <a href="/aviso-legal">Aviso legal</a>
      <a href="/privacidad">Privacidad</a>
      <a href="/accesibilidad">Declaración de accesibilidad</a>
    </footer>
  5. Texto alternativo sin información

    Grave

    1 vez en esta página · WCAG 1.1.1 (A) · EN 301 549 9.1.1.1

    Hay imágenes cuyo alt es un nombre de archivo, un código o una palabra genérica como «imagen» o «foto».

    Por qué importa

    Un alt que dice «DSC_0042.jpg» o «producto» cumple la forma pero no la función: la persona sigue sin saber qué hay en la imagen. Suele pasar cuando el catálogo se importó de golpe y se rellenó el campo automáticamente.

    Cómo se arregla

    Describe el contenido concreto. Para producto, la fórmula que funciona es: qué es + característica distintiva + variante. «Camiseta de algodón orgánico color arena» sirve; «producto» no.

    En tu plataforma · Shopify

    Si importaste el catálogo con un CSV, revisa la columna «Image Alt Text» y vuelve a importar con descripciones reales en lugar del nombre de archivo.

    Así está
    <img src="/p1.jpg" alt="imagen">
    <img src="/p2.jpg" alt="DSC_0042.jpg">
    Así debería estar
    <img src="/p1.jpg" alt="Zapatilla de running gris con suela naranja">
    <img src="/p2.jpg" alt="Mochila de lona negra de 20 litros, vista lateral">
    Ver dónde ocurre
    • body.template-index > div.grid:nth-of-type(3) > div.card:nth-of-type(2) > a:nth-of-type(1) > img
      <img src="/cdn/shop/products/sudadera.jpg" alt="imagen">
  6. Marco incrustado sin título

    Grave

    1 vez en esta página · WCAG 4.1.2, 2.4.1 (A) · EN 301 549 9.4.1.2

    Hay un <iframe> sin atributo title.

    Por qué importa

    Al navegar por lectores de pantalla se pueden listar los marcos de la página. Sin título aparecen como «marco», «marco», «marco», y hay que entrar en cada uno para saber cuál es el vídeo, cuál el mapa y cuál el chat.

    Es una corrección de treinta segundos por marco y sale en todos los informes de auditoría.

    Cómo se arregla

    Añade un title que describa qué contiene el marco. Si el iframe es un píxel de seguimiento invisible, márcalo con aria-hidden="true" además de ocultarlo.

    En tu plataforma · Shopify

    Si el vídeo viene de un bloque del tema, edita la plantilla en Tienda online › Temas › Editar código y añade el title al iframe.

    Así está
    <iframe src="https://www.youtube.com/embed/xyz"></iframe>
    Así debería estar
    <iframe src="https://www.youtube.com/embed/xyz"
            title="Vídeo: cómo elegir tu talla"></iframe>
    Ver dónde ocurre
    • body.template-index > iframe
      <iframe src="https://www.youtube.com/embed/dQw4w9WgXcQ" width="560" height="315"></iframe>
  7. El placeholder hace de etiqueta

    Grave

    1 vez en esta página · WCAG 3.3.2 (A) · EN 301 549 9.3.3.2

    Hay campos cuyo único nombre accesible viene del atributo placeholder.

    Por qué importa

    El texto del placeholder desaparece en cuanto la persona empieza a escribir. Quien se distrae a mitad de un formulario ya no puede saber qué iba en ese campo, y quien tiene dificultades de memoria o atención se queda sin referencia. Además su contraste suele ser bajísimo por diseño.

    Cómo se arregla

    Añade un <label> visible. Puedes mantener el placeholder como ejemplo del formato («ej. 28001»), pero nunca como sustituto del nombre del campo.

    Así está
    <input type="text" name="cp" placeholder="Código postal">
    Así debería estar
    <label for="cp">Código postal</label>
    <input type="text" id="cp" name="cp"
           placeholder="ej. 28001" autocomplete="postal-code">
    Ver dónde ocurre
    • body.template-index > div.header:nth-of-type(1) > form.search > input
      <input type="text" name="q" placeholder="Buscar productos">
  8. Tabla de datos sin celdas de encabezado

    Grave

    1 vez en esta página · WCAG 1.3.1 (A) · EN 301 549 9.1.3.1

    Hay una tabla con datos pero sin ninguna celda <th>.

    Por qué importa

    En una tabla bien marcada, el lector de pantalla anuncia «Talla: M, Precio: 19 €» al moverse por las celdas. Sin encabezados solo lee «M, 19 €», y la persona tiene que recordar el orden de las columnas.

    Cómo se arregla

    Convierte la primera fila (o columna) en <th> y añade scope="col" o scope="row".

    En tu plataforma · Shopify

    Las tablas de guía de tallas suelen escribirse en el editor enriquecido de la descripción del producto; edita el HTML desde el botón «</>».

    Así está
    <tr><td>Talla</td><td>Precio</td></tr>
    <tr><td>M</td><td>19 €</td></tr>
    Así debería estar
    <tr><th scope="col">Talla</th><th scope="col">Precio</th></tr>
    <tr><td>M</td><td>19 €</td></tr>
    Ver dónde ocurre
    • body.template-index > div.sizes:nth-of-type(4) > table
      <table> <tr><td>Talla</td><td>Pecho</td><td>Largo</td></tr> <tr><td>S</td><td>96 cm</td><td>68 cm</td></tr> <tr><td>M</td><td>101 cm</td><td>70 cm</td></tr> </table>
  9. El indicador de foco está desactivado

    Grave

    1 vez en esta página · WCAG 2.4.7 (AA) · EN 301 549 9.2.4.7

    El CSS elimina el contorno del foco (a:focus) sin poner nada visible en su lugar.

    Por qué importa

    Quien navega con el tabulador necesita ver dónde está. Sin indicador de foco, la persona pulsa Tab y no sabe qué elemento tiene seleccionado: navegar se vuelve adivinar. Es de los fallos más incapacitantes y de los más fáciles de arreglar.

    Un solo `outline: none` en el CSS del tema puede hacer inoperable toda la tienda por teclado.

    Cómo se arregla

    Nunca uses outline: none sin sustituto. Si el contorno por defecto no encaja con el diseño, dibuja el tuyo, con un contraste de al menos 3:1 contra el fondo.

    Así está
    a:focus, button:focus { outline: none; }
    Así debería estar
    a:focus-visible, button:focus-visible {
      outline: 3px solid #005fcc;
      outline-offset: 2px;
    }
    Ver dónde ocurre
    • a:focus
      a:focus { outline: none }
  10. Elemento clicable inalcanzable por teclado

    Grave

    1 vez en esta página · WCAG 2.1.1, 4.1.2 (A) · EN 301 549 9.2.1.1

    Hay un <div> con manejador de clic pero sin rol ni posición en el orden de tabulación.

    Por qué importa

    El ratón puede hacer clic en cualquier cosa; el teclado no. Un <div> con onclick es invisible para quien navega con tabulador, con conmutador o con control por voz. Si ese div es «Añadir al carrito», la tienda no es utilizable.

    Es el fallo que con más frecuencia deja un checkout completamente bloqueado.

    Cómo se arregla

    Usa <button>. Resuelve el foco, la activación con Enter y espacio, y el anuncio del rol, todo de una vez y sin JavaScript adicional.

    Así está
    <div onclick="anadirAlCarrito()">Añadir al carrito</div>
    Así debería estar
    <button type="button" onclick="anadirAlCarrito()">Añadir al carrito</button>
    Ver dónde ocurre
    • body.template-index > div.hero:nth-of-type(2) > div.cta
      <div class="cta" onclick="location.href='/collections/novedades'">Ver la colección</div>
  11. Vídeo sin subtítulos

    Grave

    1 vez en esta página · WCAG 1.2.2 (A) · EN 301 549 9.1.2.2

    Hay un <video> sin pista de subtítulos.

    Por qué importa

    Sin subtítulos, el vídeo no existe para quien no oye. Y tampoco para la mayoría de gente que navega con el móvil en silencio, que es casi todo el mundo.

    Cómo se arregla

    Añade un <track kind="captions"> con un archivo WebVTT. Si el vídeo está alojado en YouTube o Vimeo, activa los subtítulos allí y revísalos: los automáticos suelen tener errores.

    Así está
    <video src="/promo.mp4" controls></video>
    Así debería estar
    <video src="/promo.mp4" controls>
      <track kind="captions" src="/promo-es.vtt" srclang="es" label="Español" default>
    </video>
    Ver dónde ocurre
    • body.template-index > div.hero:nth-of-type(2) > video
      <video src="/cdn/shop/videos/hero.mp4" autoplay loop></video>
  12. Contenido con sonido que se reproduce solo

    Grave

    1 vez en esta página · WCAG 1.4.2 (A) · EN 301 549 9.1.4.2

    Hay un <video> con autoplay sin silenciar.

    Por qué importa

    El audio inesperado se superpone a la voz del lector de pantalla y hace ilegible la página hasta que se consigue parar. Encontrar el botón de pausa sin ver la pantalla, mientras suena, es exactamente lo difícil que parece.

    Cómo se arregla

    Quita el autoplay, o añade muted. Si necesitas reproducción automática, que dure menos de tres segundos o que tenga un control de parada visible al principio de la página.

    Así está
    <video src="/hero.mp4" autoplay loop></video>
    Así debería estar
    <video src="/hero.mp4" autoplay loop muted playsinline></video>
    Ver dónde ocurre
    • body.template-index > div.hero:nth-of-type(2) > video
      <video src="/cdn/shop/videos/hero.mp4" autoplay loop></video>
  13. Falta el idioma del documento

    Grave

    1 vez en esta página · WCAG 3.1.1 (A) · EN 301 549 9.3.1.1

    El elemento <html> no declara un idioma válido.

    Por qué importa

    El lector de pantalla elige la voz y la pronunciación según ese atributo. Sin él, una tienda en español puede leerse con fonética inglesa: «camiseta» suena a «kam-eye-set-ah» y no se entiende nada.

    Corrección de treinta segundos con impacto en toda la web. Empieza por aquí.

    Cómo se arregla

    Añade lang="es" al elemento <html>. Es un atributo, en una línea, y arregla la página entera.

    En tu plataforma · Shopify

    En layout/theme.liquid, la primera línea debe ser <html lang="{{ request.locale.iso_code }}">.

    Así está
    <html>
    Así debería estar
    <html lang="es">
  14. La página impide ampliar con el zoom

    Grave

    1 vez en esta página · WCAG 1.4.4 (AA) · EN 301 549 9.1.4.4

    La etiqueta viewport bloquea el zoom (width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no).

    Por qué importa

    Mucha gente amplía la pantalla del móvil para leer. Bloquearlo por motivos de diseño les deja sin acceso al contenido, sin más. La norma exige poder ampliar al menos al 200 %.

    Cómo se arregla

    Quita user-scalable=no y cualquier maximum-scale menor que 2.

    Así está
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    Así debería estar
    <meta name="viewport" content="width=device-width, initial-scale=1">
    Ver dónde ocurre
    • head > meta:nth-of-type(2)
      <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
  15. Niveles de encabezado saltados

    Moderado

    1 vez en esta página · WCAG 1.3.1 (A) · EN 301 549 9.1.3.1

    La página pasa de un nivel de encabezado a otro saltándose los intermedios (de h1 a h4).

    Por qué importa

    Los encabezados son el índice con el que se navega una página con lector de pantalla. Si los niveles saltan, ese índice deja de reflejar la jerarquía real y la persona no sabe si la sección nueva depende de la anterior o empieza de cero.

    Cómo se arregla

    Usa los niveles en orden. Si saltas un nivel por el tamaño de letra, cambia el nivel al correcto y ajusta el tamaño con CSS.

    Así está
    <h1>Tienda</h1>
    <h4>Ofertas</h4>
    Así debería estar
    <h1>Tienda</h1>
    <h2 class="titulo-pequeno">Ofertas</h2>
    Ver dónde ocurre
    • body.template-index > h4
      <h4>Más vendidos</h4>
  16. Rol ARIA inexistente

    Moderado

    1 vez en esta página · WCAG 4.1.2 (A) · EN 301 549 9.4.1.2

    Hay un elemento con role="buton", que no es un rol válido.

    Por qué importa

    Un rol mal escrito no hace nada: el navegador lo ignora y el elemento se expone con su semántica original, que casi siempre es «ningún significado». El desarrollador cree haberlo arreglado y no lo ha hecho.

    Cómo se arregla

    Corrige el nombre del rol, o quítalo y usa el elemento HTML nativo correspondiente, que ya trae el rol correcto.

    Así está
    <span role="buton">Comprar</span>
    Así debería estar
    <button type="button">Comprar</button>
    Ver dónde ocurre
    • body.template-index > span
      <span role="buton" aria-labl="ayuda" tabindex="4">Ayuda</span>
  17. Atributo ARIA inexistente

    Moderado

    1 vez en esta página · WCAG 4.1.2 (A) · EN 301 549 9.4.1.2

    Hay un elemento con el atributo aria-labl, que no forma parte de la especificación.

    Por qué importa

    Igual que con los roles inventados: el navegador lo descarta en silencio. Suelen ser erratas (aria-labl, aria-describe) que dejan el elemento sin el nombre o la descripción que se pretendía darle.

    Cómo se arregla

    Revisa la ortografía del atributo contra la especificación WAI-ARIA.

    Ver dónde ocurre
    • body.template-index > span
      <span role="buton" aria-labl="ayuda" tabindex="4">Ayuda</span>
  18. tabindex con valor positivo

    Moderado

    1 vez en esta página · WCAG 2.4.3 (A) · EN 301 549 9.2.4.3

    Hay elementos con tabindex="4".

    Por qué importa

    Un tabindex positivo saca al elemento de su sitio en el orden de tabulación y lo pone antes que todo lo demás. El resultado es que el foco salta por la página en un orden que no se corresponde con lo que se ve, y a medida que la página crece se vuelve imposible de mantener.

    Cómo se arregla

    Usa tabindex="0" para hacer focalizable un elemento, o tabindex="-1" para poder enfocarlo por programación. Si el orden no es el correcto, cambia el orden del HTML.

    Ver dónde ocurre
    • body.template-index > span
      <span role="buton" aria-labl="ayuda" tabindex="4">Ayuda</span>
  19. Falta la región de contenido principal

    Moderado

    1 vez en esta página · WCAG 1.3.1 (A) · EN 301 549 9.1.3.1

    La página no tiene <main>, o tiene más de uno.

    Por qué importa

    El atajo «ir al contenido principal» es la forma más rápida de saltarse el menú, que se repite igual en todas las páginas. Sin <main> ese atajo no existe y hay que tabular por el menú entero cada vez.

    Cómo se arregla

    Envuelve el contenido propio de la página (no el cabecero, el menú ni el pie) en un único <main>.

  20. Identificadores duplicados

    Leve

    1 vez en esta página · WCAG 4.1.1 (A) · EN 301 549 9.4.1.1

    El identificador «col» aparece 3 veces.

    Por qué importa

    Las referencias de accesibilidad (label for, aria-labelledby, aria-describedby) apuntan a un id y siempre resuelven al primero que encuentran. Con ids duplicados, la etiqueta de un campo puede acabar describiendo otro.

    Cómo se arregla

    Haz único cada id. Si viene de un componente repetido, añádele un sufijo con el índice o el identificador del producto.

    Ver dónde ocurre
    • #col
      <div id="col"><a href="/pages/privacidad">Política de privacidad</a></div>

Para revisar a mano

  • Referencia ARIA a un identificador que no existe

    El atributo aria-labelledby apunta a los identificadores titulo-inexistente, que no están en la página.

    Comprueba que el id existe y coincide exactamente, mayúsculas incluidas. Si el elemento de destino ya no existe, sustituye la referencia por un aria-label.

  • Campos de datos personales sin autocomplete

    Hay campos que piden datos personales habituales (correo, teléfono, dirección) sin atributo autocomplete.

    Añade el token estándar correspondiente: autocomplete="email" en este caso.

  • Campo obligatorio solo indicado visualmente

    La etiqueta del campo indica que es obligatorio (con un asterisco o con la palabra), pero el campo no lo declara con required ni aria-required.

    Añade el atributo required al campo. Mantén también la indicación visual: las dos cosas, no una u otra.

  • Faltan regiones de referencia

    La página no marca alguna de sus regiones principales: navigation, banner, contentinfo.

    Usa las etiquetas semánticas correctas: <header>, <nav>, <main> y <footer>, en lugar de <div class="header">.

  • Texto extremadamente pequeño

    Hay texto por debajo de 10 px (9px).

    Sube a 12 px como mínimo, y a 16 px en el contenido principal. Usa unidades relativas (rem) para que respete los ajustes del navegador.

Lo que ya está bien

  • Imágenes sin texto alternativo
  • Texto alternativo redundante
  • Icono SVG con significado pero sin nombre
  • Enlaces que muestran la URL completa
  • Falta el encabezado principal, o hay más de uno
  • La página no tiene encabezados
  • Encabezados vacíos
  • Elemento con rol interactivo pero sin nombre
  • Título de página ausente o vacío

Hasta dónde llega este informe

Hemos analizado una sola página, con el HTML y el CSS que sirve el servidor. No ejecutamos JavaScript, así que lo que se genera después de cargar (menús desplegables, modales, pasos del checkout) no entra. Y ninguna herramienta automática cubre más del 30-40 % de los criterios WCAG: el resto exige que una persona pruebe la tienda con teclado y lector de pantalla.

Referencias

Este informe no constituye asesoramiento jurídico.

¿Te mandamos esto por escrito?

Te enviamos este informe en PDF, por qué orden conviene arreglarlo y un aviso si la ley cambia en algo que te afecte. Lo escribe una persona, no es un boletín automático, y no compartimos tu dirección con nadie.

Lo usamos solo para esto.

Vigila que no vuelva a romperse

Cada cambio de tema, cada app nueva y cada producto importado puede reintroducir estas barreras. Con el seguimiento analizamos tu tienda entera cada semana, te avisamos si algo empeora y guardamos el histórico con fecha, que es justo lo que se enseña si alguien pregunta.

Ver planes