[{"content":"Hace un tiempo estuve trabajando con un equipo de desarrolladores en un design system. Nos tocaba modificar un componente de calendario típico, donde el usuario podía hacer click sobre un campo de texto para ingresar una fecha, y al hacerlo, se desplegaría un modal con un selector de día, mes y año.\nLa idea, de primeras, parecía bastante sencilla. Yo acababa de entrar en el proyecto y no había visto los diseños que se habían hecho para este componente ni tampoco la documentación de accesibilidad, por lo que me dí de lleno con la página del componente en su Storybook. Agárrate los pantalones porque se viene idea revolucionaria:\ncuando el usuario pulsaba la tecla Enter estando en el campo de edición, se abriría automáticamente un cuadro de diálogo para la selección de fechas. En código, sería algo así:\n\u0026lt;label for=\u0026#34;dateInput\u0026#34;\u0026gt;Seleccionar Fecha\u0026lt;/label\u0026gt; \u0026lt;input type=\u0026#34;text\u0026#34; id=\u0026#34;dateInput\u0026#34; aria-haspopup=\u0026#34;dialog\u0026#34; aria-expanded=\u0026#34;false\u0026#34; aria-controls=\u0026#34;dialogBox\u0026#34; /\u0026gt; \u0026lt;div id=\u0026#34;dialogBox\u0026#34; role=\u0026#34;dialog\u0026#34;...\u0026gt;\u0026lt;/div\u0026gt; Para empezar, utilizar aria-haspopup y aria-expanded en un campo de edición resultaba, cuanto menos, inusual. Pero más allá de eso, la verdadera complicación radicaba en que al presionar Enter, el diálogo no se enfocaba correctamente. A parte de que te estás comiendo el comportamiento de la tecla enter, estás haciendo que el usuario no se entere de que se ha abierto el selector.\nCuando vi esto me puse a flipar en colores, y eso que soy ciego total y no he visto colores en la vida. Propuse entonces, pensando en la idea de los skip links (enlaces que solo se visualizan con el foco de teclado) crear un botón al lado del cuadro de edición para que el usuario de teclado (atención, teclado, no lector de pantalla) pueda pulsar enter y espacio para que se abra el cuadro de diálogo con el selector de fechas.\nA priori era una idea guay, y pensando en posibles confusiones, intenté dejar claro con código CSS que el botón de seleccionar fecha debe ser visible siempre que el usuario tenga el foco de teclado ahí. Mi ejemplo era algo parecido a lo siguiente:\n\u0026lt;button class=\u0026#34;select-date\u0026#34; aria-haspopup=\u0026#34;Dialog\u0026#34; aria-label=\u0026#34;Seleccionar Fecha\u0026#34; aria-expanded=\u0026#34;true/false\u0026#34;\u0026gt; \u0026lt;svg del iconito del calendario que UX había creado/\u0026gt; \u0026lt;/button\u0026gt; .select-date { position: absolute; top: -40px; /* no se ve */ left: 10px; background-color: #0073e6; color: white; padding: 8px 16px; transition: top 0.3s; text-decoration: none; } .select-date:focus { top: 10px; /* Lo pone en pantalla */ } Esto estaba genial, de hecho cuando llegó la nueva revisión del componente mi intención era aprobarlo con un \u0026ldquo;wow, qué chulo!\u0026rdquo; han hecho un selector de fecha súper accesible y ahora el usuario de teclado ya no se va a perder. Pero esperaos un momento, que voy a consultarlo con mi compañero de visual, a ver que no sea que se rompa la UI o algo.\nCuál fue mi sorpresa cuando mi compañero me dijo que habían pasado de mi código de ejemplo. Cuando el usuario estaba en el cuadro de edición, todo guay, pero al hacer tab, el foco de teclado se iba al limbo perdido, más allá de los confines del espacio interestelar. el lector de pantalla, sin embargo y correctamente, anunciaba que el foco estaba en el botón Seleccionar Fecha.\nHablando con los compañeros desarrolladores, se ve que habían asumido que ese botón era invisible. Total, para qué vas a poner que se vea el botón, si es un usuario de teclado y lector de pantalla?\nAhí está el quid de la cuestión, alguien se había tomado la libertad de asumir que un usuario de teclado es usuario de lector de pantalla siempre, y ese ese es el error que nunca debemos cometer. Usuarios de teclado pueden ser muchos y muy variados, desde personas que tienen poca movilidad en la mano y no pueden usar el ratón, personas con baja visión, personas que utilicen dispositivos de control alternativos\u0026hellip;\nConclusión sobre este caso #Hay que leer la documentación que te han dado. Si eres desarrollador y no sabes mucho de accesibilidad o estás aprendiendo, si te ponen un ejemplo para un botón que aparece visualmente con el foco, no pases. Tampoco hagas un cuadro de edición con un haspopup y un expanded, por favor.\n","date":"4 de diciembre de 2024","permalink":"https://accesibilidad.oriolgomez.com/posts/cuadro-edicion-dialogo-foco/","section":"Artículos","summary":"\u003cp\u003eHace un tiempo estuve trabajando con un equipo de desarrolladores en un design system. Nos tocaba modificar un componente de calendario típico, donde el usuario podía hacer click sobre un campo de texto para ingresar una fecha, y al hacerlo, se desplegaría un modal con un selector de día, mes y año.\u003c/p\u003e\n\u003cp\u003eLa idea, de primeras, parecía bastante sencilla. Yo acababa de entrar en el proyecto y no había visto los diseños que se habían hecho para este componente ni tampoco la documentación de accesibilidad, por lo que me dí de lleno con la página del componente en su Storybook. Agárrate los pantalones porque se viene idea revolucionaria:\u003c/p\u003e","title":"El cuadro de edición que abre diálogo y el foco que desapareció"},{"content":"Con este encabezado, cuyo título tiene bastante parecido a cierta película bastante buena, quiero presentaros otro caso que estoy viendo últimamente muchas veces en páginas webs de transmisión de audio y vídeo. atención a este código:\n\u0026lt;button id=\u0026#34;muteButton\u0026#34; aria-pressed=\u0026#34;false\u0026#34; onclick=\u0026#34;toggleMicrophoneState()\u0026#34;\u0026gt;Silenciar el micrófono\u0026lt;/button\u0026gt; function toggleMicrophoneState() { var button = document.getElementById(\u0026#39;muteButton\u0026#39;); let isPressed = button.getAttribute(\u0026#39;aria-pressed\u0026#39;) == \u0026#39;true\u0026#39;; isPressed = !isPressed; // Cambia el estado de aria-pressed button.setAttribute(\u0026#39;aria-pressed\u0026#39;, isPressed); // Cambia el texto del botón if (isPressed) { button.textContent = \u0026#39;Reactivar el Micrófono\u0026#39;; } else { button.textContent = \u0026#39;Silenciar el Micrófono\u0026#39;; } } A priori es una idea bastante chula. qué guay, le estoy diciendo al usuario de lector de pantalla que el botón, cuando está pulsado, significa que el micro está muteado y que si hace click lo volverá a desactivar. Vamos a cambiar el texto del botón también, para que así haya menos confusión aún, para que quede bien claro. ¿No?\nBien, presta atención a lo que dice NVDA cuando el usuario pasa por encima de este botón:\nSilenciar el Micrófono botón conmutador sin pulsar Hasta ahí bien. Nos está diciendo que el micrófono está silenciado. Si lo pulso, el botón estará pulsado y ya está, ¿no?\nReactivar el Micrófono botón conmutador pulsado vamos a desgranar esto. Por un lado nos está diciendo que tenemos un botón, que se llama Reactivar Micrófono, y que está pulsado. ¿Eso significa que el micrófono está activado o que está silenciado y que el botón está pulsado. ¿Tengo el micro encendido o apagado?\nIncluso en Google Meet lo hacen un poquito mal (a estos sí que no me importa mencionarlos, ahora veréis por qué digo que solo lo hacen un poquito mal). Cuando estamos en una llamada de Google Meet, tenemos lo siguiente.\nDesactivar micrófono botón conmutador sin pulsar intro Tu micrófono está desactivado. Activar micrófono botón conmutador pulsado intro Tu micrófono está activado. Desactivar micrófono botón conmutador sin pulsar Esto es de los comportamientos más liosos que me he encontrado. Por un lado, está guay que creen una región dinámica que anuncie el estado del micro y que haya un acceso directo (Control + D) para cambiar el estado del micro rápidamente. ¿Pero realmente hacía falta que ese botón cambiara su texto de forma dinámica?\nMi opinión es que no. Tan solo con añadir el texto silenciar Micrófono, y cambiando su atributo aria-pressed de true a false, tendríamos una experiencia mucho más fluida, algo así como:\nSilenciar micrófono botón conmutador sin pulsar Quiero mutear el micrófono y le doy al espacio\u0026hellip;\nSilenciar el Micrófono botón conmutador pulsado De esta manera, es mucho más sencillo para el usuario saber si el micrófono está silenciado o no, sin tener que recurrir a preguntar si se le escucha o fijarse en una región dinámica (que no todas las plataformas de transmisión tienen).\nEste mismo comportamiento me lo he encontrado en multitud de páginas webs y en multitud de acciones, por ejemplo:\nAñadir a favoritos sin pulsar, eliminar de favoritos pulsado; Desactivar la cámara sin pulsar, activar la cámara pulsado. Haciendo el código para este ejemplo me he liado hasta yo. Me han hecho falta 3 o 4 iteraciones para ver cuándo tenía que poner silenciar y cuándo reactivar, para que veáis lo curioso de la situación.\nConclusión sobre este caso #No te líes, y haz pruebas. Si eres desarrollador y te han mandado programar esto, asegúrate de que haces pruebas con la persona de tu empresa que se encarga de la accesibilidad. Enseguida se dará cuenta de que el comportamiento es extraño. Todos cometemos errores, y este es uno muy fácil de cometer. Pero por favor, no lo subas a producción.\n","date":"4 de diciembre de 2024","permalink":"https://accesibilidad.oriolgomez.com/posts/el-curioso-caso-de-pressed-button/","section":"Artículos","summary":"\u003cp\u003eCon este encabezado, cuyo título tiene bastante parecido a cierta película bastante buena, quiero presentaros otro caso que estoy viendo últimamente muchas veces en páginas webs de transmisión de audio y vídeo. atención a este código:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-html\" data-lang=\"html\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ebutton\u003c/span\u003e \u003cspan class=\"na\"\u003eid\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;muteButton\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003earia-pressed\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;false\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003eonclick\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;toggleMicrophoneState()\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003eSilenciar el micrófono\u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ebutton\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003etoggleMicrophoneState\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"nx\"\u003ebutton\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003edocument\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003egetElementById\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;muteButton\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"kd\"\u003elet\u003c/span\u003e \u003cspan class=\"nx\"\u003eisPressed\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003ebutton\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003egetAttribute\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;aria-pressed\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;true\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nx\"\u003eisPressed\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003eisPressed\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"c1\"\u003e// Cambia el estado de aria-pressed\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nx\"\u003ebutton\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003esetAttribute\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;aria-pressed\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eisPressed\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"c1\"\u003e// Cambia el texto del botón\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eisPressed\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nx\"\u003ebutton\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etextContent\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;Reactivar el Micrófono\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nx\"\u003ebutton\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etextContent\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;Silenciar el Micrófono\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eA priori es una idea bastante chula. qué guay, le estoy diciendo al usuario de lector de pantalla que el botón, cuando está pulsado, significa que el micro está muteado y que si hace click lo volverá a desactivar. Vamos a cambiar el texto del botón también, para que así haya menos confusión aún, para que quede bien claro. ¿No?\u003c/p\u003e","title":"El curioso caso de Pressed Button"},{"content":"Una guía sobre lo que, como desarrollador, no tienes que repetir.\nEn un mundo cada vez más interconectado y donde las leyes sobre la accesibilidad parece que van tomando fuerza, la accesibilidad web se ha convertido en un componente esencial del diseño y desarrollo de sitios web. Cómo crear contenido digital accesible sin ser un peligro es una guía práctica diseñada para ayudar a desarrolladores, diseñadores y gestores de contenido a crear experiencias web inclusivas y accesibles para todas las personas sin cometer errores fáciles de cometer por desconocimiento.\nEste libro nace de la creciente necesidad de entender la accesibilidad desde un punto de vista técnico. No estoy aquí para hablarte de los últimos avances en leyes y normas en Estados Unidos y la Unión Europea, o para enseñarte a hacer menús desplegables que funcionen bien con el teclado. Ya hay muchos libros sobre eso. Con esta pequeña guía, quiero contarte qué es lo que no hay que hacer. Es un compendio de algunos de los errores más apabullantes en páginas web o aplicaciones que he encontrado en proyectos y empresas donde he trabajado o contenido digital con el que me he topado como usuario.\nA lo largo de este libro, veremos algunos de los errores más enrevesados cometidos en materia de accesibilidad, por supuesto sin citar fuentes. No es mi intención ridiculizar a nadie. La idea es que este libro sirva de guía educativa para evitar cometer las mismas atrocidades, con un poco de humor negro que quienes me conocen, saben que a veces me caracteriza, proporcionando ejemplos prácticos y consejos accionables. Quiero que dispongas de las herramientas necesarias para que puedas desarollar páginas webs accesibles sin que se rían de ti.\nPrepárate para descubrir cómo no hacer skip links que hacen que el foco de teclado desaparezca y qué es lo que has hecho mal para que el aria-label que acabas de poner en tu web aparezca en Mastodon de lo inútil o malo que es.\n","date":null,"permalink":"https://accesibilidad.oriolgomez.com/","section":"Accesibilidad digital sin ser un peligro","summary":"\u003cp\u003e\u003cem\u003eUna guía sobre lo que, como desarrollador, no tienes que repetir.\u003c/em\u003e\u003c/p\u003e\n\u003cp\u003eEn un mundo cada vez más interconectado y donde las leyes sobre la accesibilidad parece que van tomando fuerza, la accesibilidad web se ha convertido en un componente esencial del diseño y desarrollo de sitios web. \u003cem\u003eCómo crear contenido digital accesible sin ser un peligro\u003c/em\u003e es una guía práctica diseñada para ayudar a desarrolladores, diseñadores y gestores de contenido a crear experiencias web inclusivas y accesibles para todas las personas sin cometer errores fáciles de cometer por desconocimiento.\u003c/p\u003e","title":"Accesibilidad digital sin ser un peligro"},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/tags/aria/","section":"tags","summary":"","title":"ARIA"},{"content":"Casos reales que me he encontrado auditando y usando la web, con el error, por qué falla y cómo arreglarlo.\n","date":null,"permalink":"https://accesibilidad.oriolgomez.com/posts/","section":"Artículos","summary":"\u003cp\u003eCasos reales que me he encontrado auditando y usando la web, con el error, por qué falla y cómo arreglarlo.\u003c/p\u003e","title":"Artículos"},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/tags/ckeditor/","section":"tags","summary":"","title":"ckeditor"},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/tags/dhl/","section":"tags","summary":"","title":"DHL"},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/tags/email/","section":"tags","summary":"","title":"email"},{"content":"Hoy no os traigo un caso de un design system, ni de una auditoría en producción, ni de un Storybook con ideas revolucionarias. Hoy viene algo mucho más doméstico y bueno, de envíos a casa va la cosa. Un correo electrónico. Uno de esos de \u0026ldquo;utilice este código para verificar su cuenta\u0026rdquo;. Lo de toda la vida. Pides el código, te llega, lo copias, lo pegas y a otra cosa mariposa. ¿Qué puede salir mal en un correo con un número de seis cifras? Agárrate los pantalones, que se viene curva.\nEl correo, en teoría, dice esto:\nUtilice este código de acceso, 744768 para verificar el correo electrónico de su cuenta de On Demand Delivery. El código expirará en 15 minutos. (no lo uséis que ya lo he verificado) ;)\nQuince minutos. Apuntaos ese dato, que al final vuelve.\nAhora, esto es lo que llegó a mi bandeja de entrada (os lo recorto, que el original es peor que los petardos en la verbena de Sant Joan):\n\u0026lt;div aria-describedby=\u0026#34;cke_123\u0026#34; title=\u0026#34;Rich Text Editor, BODY\u0026#34; aria-label=\u0026#34;Rich Text Editor, BODY\u0026#34; role=\u0026#34;textbox\u0026#34; id=\u0026#34;m_-2304999226856719163BODY\u0026#34;\u0026gt; Utilice este código de acceso \u0026lt;strong\u0026gt;744768\u0026lt;/strong\u0026gt; para verificar el correo electrónico de su cuenta de On Demand Delivery. El código expirará en 15 minutos. \u0026lt;/div\u0026gt; ¿Veis el percal? Cada bloque del correo —el saludo, el cuerpo, la firma, hasta el pie— viene envuelto en su propio \u0026lt;div\u0026gt; con un role=\u0026quot;textbox\u0026quot;, un aria-label que reza \u0026ldquo;Rich Text Editor, LO-QUE-SEA\u0026rdquo;, un title clavadito al aria-label y, de propina, un aria-describedby=\u0026quot;cke_123\u0026quot;. A saber lo ke era, digo que\u0026hellip; eso digo yo\u0026hellip; Algo de CKEditor, me suena me suena, de haber trabajado con un cliente que lo usaba\u0026hellip; No, no era DHL. era gente más guay.\nEso es. Ese cke_ del principio es la pista que lo resuelve todo. Es CKEditor. El notas que ha montao esta plantilla la ha metido en un editor de texto enriquecido, le ha dao al guardar y, en vez de pillar el HTML limpio que te saca el editor, ha metido el DOM del propio editor porque patata y venga, copypaste al correo en toda regla. Es decir: al lector de pantalla no le llega un correo. Llega una captura del editor pero con ARIA labels mal puestos.\nVamos a desgranar por qué esto es una bomba. Cuando le pones role=\u0026quot;textbox\u0026quot; a un div, le estás diciendo al lector de pantalla \u0026ldquo;esto es un campo de edición, un control de formulario, aquí se escribe\u0026rdquo;. Es un div con texto dentro, pero tú lo has disfrazado de input. Bueno, en verdad no está disfrazado, pero al copiarlo del editor, es lo que recibe el usuario. un falso editor.\n¿Y qué hace un lector de pantalla cuando se topa con un campo de formulario? Anuncia su nombre accesible. ¿Y de dónde sale ese nombre? Pues el aria-label gana por goleada. Así que el nombre de este campo es, literalmente, \u0026ldquo;Rich Text Editor, BODY\u0026rdquo;. El contenido —el código 744768, los quince minutos, todo— pasa a ser el valor del campo, no su nombre. Y en modo navegación el lector colapsa el campo entero a su etiqueta y sigue su camino. El contenido se evapora.\nEl title repite la misma cantinela por si quedaba alguna duda. Y el aria-describedby=\u0026quot;cke_123\u0026quot; apunta a un elemento con id=\u0026quot;cke_123\u0026quot; que\u0026hellip; no existe. Vivía dentro del editor, no dentro del correo. Una referencia colgando en el vacío, el wave creo que le llama orphaned ARIA attribute.\n¿El resultado? Esto es, palabra por palabra, lo único que mi lector de pantalla llegó a leer:\nRich Text Editor, MAIN_HEADING Rich Text Editor, GREETING Rich Text Editor, BODY Rich Text Editor, SIGNATURE_LINE1 Rich Text Editor, SIGNATURE_LINE2 Rich Text Editor, FOOTER_TEXT 2026 © DHL International GmbH. All rights reserved. Fijaos en el detalle más fino de todos: la única línea que sobrevive entera y legible es el copyright. ¿Por qué? Porque es el único trozo que no sale de la plantilla del editor. Al menos sabemos dónde denunciar.\nY aquí está el quid de la cuestión. Tenemos un correo de verificación, que tengo que usar para entrar en la web, con un código que caduca en quince minutos y bueno, yo porque me las doy un poco de poweruser y el navegador de objetos de NVDA me salvó la vida, que si no, no habría podido leer el correo sin un OCR o sin una IA para describir las fotos. Si es que al final la IA sirve para algo.\nAhora ponte en la piel de una persona mayor o que no sabe mucho, ya me dirás qué hace.\n¿Cómo se arregla esto? #Lo más gracioso es que no hay que arreglar nada raro. Es un puto correo. No necesita ni un solo role, ni un solo atributo ARIA. Necesita HTML semántico de toda la vida. Cosa que el CKEditor ya hubiese sacao si hubiesen hecho las cosas como toca.\n\u0026lt;p\u0026gt;Utilice este código de acceso \u0026lt;strong\u0026gt;744768\u0026lt;/strong\u0026gt; para verificar el correo electrónico de su cuenta de On Demand Delivery. El código expirará en 15 minutos.\u0026lt;/p\u0026gt; Si montas tus plantillas en un editor visual, exporta el HTML limpio (la salida, el \u0026ldquo;source\u0026rdquo;, como lo llame tu editor), no seas tan vago (o vaga) de meter el HTML del editor sin más. Que no cuesta tanto.\nConclusión sobre este caso #Un correo es lo más fácil del mundo de hacer accesible: es texto. Hay que esforzarse muchísimo para romperlo, y aun así aquí estamos. No copies y pegues el DOM de tu editor. Comprueba lo que mandas con un lector de pantalla o, como mínimo, busca \u0026ldquo;Rich Text Editor\u0026rdquo; en el HTML antes de darle a enviar. Y si eres de DHL y estás leyendo esto: sigo sin poder verificar mi cuenta. No, es broma.\n","date":"26 de junio de 2026","permalink":"https://accesibilidad.oriolgomez.com/posts/rich-text-editor-body-correo-dhl/","section":"Artículos","summary":"\u003cp\u003eHoy no os traigo un caso de un design system, ni de una auditoría en producción, ni de un Storybook con ideas revolucionarias. Hoy viene algo mucho más doméstico y bueno, de envíos a casa va la cosa. Un correo electrónico. Uno de esos de \u0026ldquo;utilice este código para verificar su cuenta\u0026rdquo;. Lo de toda la vida. Pides el código, te llega, lo copias, lo pegas y a otra cosa mariposa. ¿Qué puede salir mal en un correo con un número de seis cifras? Agárrate los pantalones, que se viene curva.\u003c/p\u003e","title":"Rich Text Editor, BODY: el correo en el que han copiado el cKEditor sin más."},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/tags/role/","section":"tags","summary":"","title":"role"},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/tags/","section":"tags","summary":"","title":"tags"},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/tags/textbox/","section":"tags","summary":"","title":"textbox"},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/tags/aria-pressed/","section":"tags","summary":"","title":"aria-pressed"},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/authors/","section":"authors","summary":"","title":"authors"},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/tags/botones-conmutador/","section":"tags","summary":"","title":"botones conmutador"},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/tags/di%C3%A1logos/","section":"tags","summary":"","title":"diálogos"},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/tags/enlaces/","section":"tags","summary":"","title":"enlaces"},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/tags/foco-de-teclado/","section":"tags","summary":"","title":"foco de teclado"},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/tags/href/","section":"tags","summary":"","title":"href"},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/tags/lectores-de-pantalla/","section":"tags","summary":"","title":"lectores de pantalla"},{"content":"Hace un tiempo estuve enredado con una web donde teníamos una serie de artículos al que el usuario podía acceder mediante enlaces, típico de las webs de noticias. La idea era que el artículo hiciera su aparición estelar tipo SPA, sin que cambiase la URL ni el título de la página (otro fallo de accesibilidad, quedarse con el título de la página principal en toda la app).\nA alguien se le encendió la lucecita y en producción, al hacer la auditoría, me topé con algo así:\n\u0026lt;a onclick=\u0026#34;showArticle(id)\u0026#34; title=\u0026#34;noticia de última hora\u0026#34;\u0026gt;noticia de última hora\u0026lt;/a\u0026gt; Pero aquí está el problema del plan, los enlaces eran como fantasmas de teclado: cualquier enlace que no tenga atributo href, pierde el foco del teclado y su funcionalidad con la tecla Enter. Es decir, si el usuario va tabulando, se saltaba la sección entera de noticias. Además, cuando se trata de webs con contenido similar, por ejemplo una secuencia de artículos, se suele envolver cada enlace a contenido con un encabezado para que la navegación sea más fluida.\nPero espera\u0026hellip; No quiero poner href, qué hago?\nAñade el atributo tabindex a los enlaces para que puedan recibir enfoque y maneja el evento Enter utilizando JavaScript. Convierte el enlace en un botón utilizando el elemento button con el rol adecuado (link o tab) según el contexto de la página. Es también importante que el usuario se entere de que se ha cargado el artículo. En esa web en particular, el artículo aparecía arriba del todo de la página sin enfocarse. Eso significa que cualquier usuario sin visión que utilice lector de pantalla, ni se va a dar cuenta de que ha aparecido el artículo por arte de magia. Para evitar eso, asigna tabindex -1 al encabezado del artículo (sí, hay que meter un encabezado también!) y llama a la función focus() una vez esté cargado. de esta manera, le ahorras al usuario tener que desplazarse arriba a la vez que le indicas que el artículo se ha cargado.\n","date":"4 de diciembre de 2024","permalink":"https://accesibilidad.oriolgomez.com/posts/los-articulos-sin-foco/","section":"Artículos","summary":"\u003cp\u003eHace un tiempo estuve enredado con una web donde teníamos una serie de artículos al que el usuario podía acceder mediante enlaces, típico de las webs de noticias. La idea era que el artículo hiciera su aparición estelar tipo SPA, sin que cambiase la URL ni el título de la página (otro fallo de accesibilidad, quedarse con el título de la página principal en toda la app).\u003c/p\u003e\n\u003cp\u003eA alguien se le encendió la lucecita y en producción, al hacer la auditoría, me topé con algo así:\u003c/p\u003e","title":"Los artículos sin foco"},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/tags/nvda/","section":"tags","summary":"","title":"NVDA"},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/authors/oriol-g%C3%B3mez-sent%C3%ADs/","section":"authors","summary":"","title":"Oriol Gómez Sentís"},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/tags/skip-links/","section":"tags","summary":"","title":"skip links"},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/tags/spa/","section":"tags","summary":"","title":"SPA"},{"content":"","date":null,"permalink":"https://accesibilidad.oriolgomez.com/tags/tabindex/","section":"tags","summary":"","title":"tabindex"},{"content":"Me llamo Oriol Gómez Sentís y durante los últimos cuatro años estoy inmerso en el mundo de la accesibilidad web. Un detalle crucial sobre mi experiencia es que soy ciego total, un aspecto que tendrá un papel bastante significativo en los casos que desarrollaré a lo largo de este libro. Normalmente, en la mayoría de empresas o consultorías, la evaluación de la accesibilidad web se lleva a cabo con la ayuda de personas que emplean lectores de pantalla, quienes se enfocan principalmente en pruebas relacionadas con el uso del teclado y los propios lectores, además de pruebas de accesibilidad relacionadas a otros aspectos menos visuales. Además, existen consultores especializados que se encargan de realizar análisis visuales, que nunca hay que dejar atrás como el color, contrastes, foco de teclado, etc.\nDigo que es importante el hecho de que soy ciego total porque en algunos de los casos, como el que viene a continuación, la ceguera jugará un papel importante sobre el problema que nos ocupa.\n","date":"1 de enero de 0001","permalink":"https://accesibilidad.oriolgomez.com/sobre-el-autor/","section":"Accesibilidad digital sin ser un peligro","summary":"\u003cp\u003eMe llamo Oriol Gómez Sentís y durante los últimos cuatro años estoy inmerso en el mundo de la accesibilidad web. Un detalle crucial sobre mi experiencia es que soy ciego total, un aspecto que tendrá un papel bastante significativo en los casos que desarrollaré a lo largo de este libro. Normalmente, en la mayoría de empresas o consultorías, la evaluación de la accesibilidad web se lleva a cabo con la ayuda de personas que emplean lectores de pantalla, quienes se enfocan principalmente en pruebas relacionadas con el uso del teclado y los propios lectores, además de pruebas de accesibilidad relacionadas a otros aspectos menos visuales. Además, existen consultores especializados que se encargan de realizar análisis visuales, que nunca hay que dejar atrás como el color, contrastes, foco de teclado, etc.\u003c/p\u003e","title":"Sobre el autor"}]