Uninstallme

Desarrollo frontend, estándares web, accesibilidad y más

El uso de iconos de banderas para la elección de idioma en un sitio web plantea una serie de problemas, tanto de usabilidad como de accesibilidad, que no lo hacen recomendable. Si buscamos un poquito en Internet y le damos un par de vueltas podemos ver que no es una buena idea y sin embargo, su uso es tan frecuente que es fácil caer en este error de diseño.

Algunos problemas del uso de banderas

Usar sólo iconos de bandera (sin texto)

Como dice Roger Johansson en Indicating language choice: flags, text, both, neither?, usar sólo una bandera es un big no-no! (Me gusta esta expresión!)

Anteriormente comenté en este blog los problemas de usar sólo iconos como enlaces, llegando a la conclusión de que los iconos siempre deberían ir acompañados de un enlace textual, o mejor dicho, ser un complemento de este y no el elemento que transmita la mayor parte de la información.

Poniéndonos en el caso de las banderas, ¿qué ocurre si un usuario es daltónico y confunde los colores de una bandera o si simplemente desconoce a qué país representa una bandera o incluso qué idioma se habla en determinado país? Y no hace falta irse a pensar en usuarios con discapacidades de ningún tipo, simplemente en la cantidad de países cuya bandera usa tres bandas de color rojo, azul y blanco.

Como decía Johansson, a big no-no!

Icono de bandera acompañada del nombre del idioma en ese mismo idioma

Esta opción es algo mejor que la anterior pero sigue planteando problemas, como por ejemplo, el de que algunos usuarios se puedan sentir ofendidos. ¿Le agrada a un estadounidense ver su idioma representado con la bandera de inglaterra o viceversa? Pues como comentan en You should never use flags for language choice, parece ser que a algunos no.

Hmm, I DO speak English, but this is not the flag of my country. I hate when I see this!

Por si estas razones no son suficientes, tenemos un documento del W3C Working Group que sin más rodeos dice “Do not use flag icons to indicate languages.” y nos da una razón indiscutible para ello: Las banderas representan países, no idiomas.

Posibles alternativas al uso de banderas

Usar sólo texto en el idioma correspondiente

Una opción simple y sencilla que no deja lugar a dudas y no ofende a nadie, pero que tiene el inconveniente de no ser tan fácilmente localizable y reconocible como los enlaces acompañados de icono.

Un select con los idiomas disponibles

Esta opción es buena cuando hay bastantes idiomas, pero tampoco está libre de problemas. ¿Qué etiqueta usamos para el label del select? Si usamos “idioma”, ¿en qué idioma lo ponemos?
Si decidimos prescindir del label, ¿qué ponemos como opción por defecto para el select? ¿”Seleccione idioma”?

Podemos recurrir al uso de un icono como el globo del mundo o algo similar que preceda al select, pero volvemos al problema de usar sólo iconos para transmitir información. Además esto require un esfuerzo extra de interpretación.

Conclusión

Vistos los problemas y las posibles alternativas (seguro que hay más), quizá la mejor opción sea la de usar sólo texto en el idioma correspondiente (Español | English | Français) y si a pesar de todo uno se decanta por el uso de banderas, acompañarlas siempre de texto.

Más información

8 Comentarios

Acabo de descubrir varios script que hacen posible, tanto la navegación “normal” mediante el botón volver del navegador, como el añadir páginas a los favoritos o marcadores en aplicaciones AJAX. Una solución a dos de los grandes problemas de usabilidad que presentan este tipo de aplicaciones.

Dejo cuatro enlaces rápidos:

  1. HistoryManager. Funciona con Mootools.
    It solves the typical “Back-Button” and “Ajax Bookmarks” problems for accessible browsing and a better usability in Rich Internet applications.
  2. Versión de HistoryManager para Prototype.
  3. History Keeper. No utiliza ninguna librería.
  4. UpdateControls: UpdateHistory and AnimatedUpdatePanel. Para ASP.NET AJAX.

Sin comentarios

Evitar el espacio extra entre elementos de lista en línea

Por kcmr, el 15 de Abril de 2009 en CSS, HTML

Etiquetas:,

Caso típico: lista centrada de enlaces al pie de página separados por barras u otro elemento.

Enlaces centrados en el pie de página

Enlaces centrados en el pie de página

Para que la lista aparezca centrada necesitamos que los elementos de lista se muestren en línea en vez de en bloque.


ul{text-align: center;}
li{display: inline; padding: 0 6px 0 5px; background: url(../img/separador.gif) 100% 50% no-repeat;}

Problema típico: la separación entre ítems no es igual en distintos navegadores, básicamente, entre Explorer y el resto.

Distinta separación entre elementos de lista en Explorer

Distinta separación entre elementos de lista en Explorer

Solución (muy vieja): evitar la separación (saltos de línea) entre los elementos de lista en el HTML.


<ul><li><a href="#">Lorem ipsum</a></li><li><a href="#">Sit amet</a></li><li><a href="#">Consectetuer</a></li></ul>

Se puede mejorar un poco la legibilidad del código y evitar tener toda la lista en una línea de esta forma:


<ul><li
><a href="#">Lorem ipsum</a></li
><li><a href="#">Sit amet</a></li
><li><a href="#">Consectetuer</a></li
></ul>

El resultado de usar esta técnica:

Misma separación entre elementos de lista en todos los navegadores

Misma separación entre elementos de lista en todos los navegadores

Demo.

Visto en CSS:Inline list, entre otras cosas muuuy interesantes.

2 Comentarios

Descanse En Paz, @import

Por kcmr, el 11 de Abril de 2009 en CSS, Navegadores

Etiquetas:

En el blog de Anieto2K aparecía hace un par de días la sentencia tajante: “No uses @import“. Y sí, después de comprobar que tiene más inconvenientes que ventajas, la sentencia no es ninguna barbaridad.

Yo también uso usaba esta técnica, que vi por primera vez en la web del W3C, donde todavía la siguen usando, y la verdad es que nunca me había dado por comprobar en qué orden cargaban los archivos. Efectivamente, usando @import dentro de una CSS, la carga de los archivos no se corresponde con el orden en que se llaman desde el HTML provocando que los script carguen antes que las hojas de estilo, etc.

Dejo aquí una captura del orden de carga de archivos tomada de la web del W3C, en la que se puede ver como home-import.css no se carga en el orden que cabría esperar, aunque como comenta Anieto, tiene toda su lógica que el orden sea el que es al usar este método.

Captura del orden de carga de archivos del W3C

Captura del orden de carga de archivos del W3C

Un poco de historia sobre el difunto @import

El uso de @import dentro de etiquetas <style> en el HTML se utilizaba anteriormente para esconder hojas de estilo a Netscape 4, que no entendía @import, de manera que, opcionalmente se podía proporcionar una CSS con estilos básicos para este navegador mediante <link> y otra con estilos “avanzados” para los demás mediante <style> y @import. Esta técnica, cuando no se proporcionaba una CSS alternativa mediante <link>, tenía el inconveniente del instante de contenido sin estilo en Internet Explorer. Existe otra técnica con la misma finalidad que no plantea ese inconveniente, basada en especificar “all” como valor para el atributo media de la etiqueta <link> o una combinación de varios medios, ya que Netscape 4 sólo entendía el valor “screen”:

<link rel="stylesheet" type="text/css" href="css/style.css" media="screen, projection" />

A día de hoy, Netscape 4 es un navegador completamente muerto, por lo que estas técnicas también pueden pasar a la historia con él.

En cuanto a @import dentro de la CSS, me parecía una buena forma de enlazar a una sola hoja de estilo en el HTML, pero visto lo visto, también podemos decirle adiós.

Más información

1 Comentario

Yo también me he sumado a esta iniciativa de dejar la web en pelotas, que pretende promover el correcto uso de Estándares Web y marcado semántico. Es el CSS Naked Day.

Me tengo que decir eso de “bueno, un día es un día” para tener la conciencia más tranquila, ya que aunque todo permanece perfectamente utilizable y comprensible sin estilos, la verdad sea dicha… resulta bastante incómodo de leer.

Una buena forma de superarlo, sobretodo cuando tenemos verdadero interés en leer algo, cosa que debe de ocurrir sólo durante un 5% del tiempo en que navegamos, es utilizar un bookmarket que aplica los estilos necesarios para mejorar la legibilidad a la parte de la página que contiene el contenido relevante, ocultando todos los demás elementos que pueden distraer la lectura, como banners, menús de navegación, etc. Se trata de Readability. En su web podemos elegir el estilo que más nos gusta entre varias opciones y una vez configurado, añadir el marcador al navegador.

Es un bookmarklet bastante útil y cómodo, no sólo para superar el día de hoy, sino para cuando nos encontramos con un tamaño de texto diminuto o longitud excesiva de líneas, dos cosas que dificultan y hacen poco apetecible la lectura.

2 Comentarios

Botones con brillo sin imágenes

Por kcmr, el 6 de Abril de 2009 en CSS

Etiquetas:

Después de ver el “cómo se hizo” de los botones de las aplicaciones de Google (Google Reader, Gmail, Google Docs), y porque me aburría un poco, me he animado a hacer algo parecido manteniendo como objetivo no usar imágenes de fondo.

Demo botones con brillo sin imágenes

Demo botones con brillo sin imágenes

Ventajas:

  • Cargan rapidamente
  • No tenemos que preocuparnos del rollover, las esquinas, etc.
  • Son escalables
  • Son fácilmente personalizables

Inconvenientes:

  • El código no es precísamente lo más limpio del mundo, ya que se utilizan cuatro elementos SPAN anidados dentro del enlace o elemento BUTTON
  • Necesitamos añadir una clase “hover” o similar mediante Javascript al primero de los SPAN anidados, ya que el :hover no funciona en Explorer 6

Antes de añadir el script para Explorer 6, tuve la oportunidad de experimentar lo que parece ser oooootro bug de este navegador. Si presionamos F5 teniendo el cursor sobre un botón, aparecen los estilos para el estado :hover. Curioso.

Demo botones con brillo sin imágenes

El código CSS usado:

Para botones con fuente Tahoma a 11 píxeles:


/* generales boton */
.boton{ text-decoration: none; border: 0; cursor: pointer; }
button.boton{ outline: none; background: none; white-space: nowrap; overflow: visible;}
.boton span.brillo span{ font: bold 1.1em tahoma, arial, sans-serif; color: #fff; display: block; text-align: center; padding: 0 .9090em; min-width: 5.6363em; top: -.5454em; position: relative; }
* html .boton span.brillo span{ width: 5.6363em; white-space: nowrap; }   /* emulacion de la propiedad min-width para Explorer 6 */
.boton span.borde-h{ display: block; float: left; }
.boton span.borde-v{ cursor: pointer; padding: 1px 0 0 1px; position: relative; margin-left: -1px; margin-right: -1px; display: block; float: left;}
.boton span.brillo{ display: block; }

Para un botón de un determinado color, en este caso verde:


/* verde */
.boton-a span.borde-h{ border: 1px solid #718a0a; border-left: 0; border-right: 0; }
.boton-a span.borde-v{ background: #defd0e; border: 1px solid #718a0a;  border-top: 0; border-bottom: 0; }
.boton-a span.brillo{ border-top: 10px solid #b4ce0c; background: #95b60d; }
.boton-a:hover span.borde-h, .boton-a span.hover{ border-color: #526407;}
.boton-a:hover span.borde-v, .boton-a .hover span.borde-v{ background: #c7e30d; border-color: #526407;}
.boton-a:hover span.brillo, .boton-a .hover span.brillo{ border-top-color: #a4bc0b; background: #79940b;}

2 Comentarios

Esta es la sintaxis del operador ternario, que equivale a una estructura de control de flujo if / else:


condicion ? instrucción si se cumple : instrucción si no se cumple;

Usando un ejemplo de código real podría ser así:


hasClassName(capa, clase) ? removeClassName(capa, clase) : addClassName(capa, clase);

Que para mayor legibilidad, si las instrucciones son muy largas, se puede separar en varias líneas:


hasClassName(capa, clase)
? removeClassName(capa, clase)
: addClassName(capa, clase);

Hasta ahora, siempre que había tenido que usar varias instrucciones en una condición, había abandonado el operador ternario en favor de una estructura if / else:


if(condicion){
    hazAlgo();
    yHazOtraCosa();
}
else{
    hazUnaCosa();
    hazOtraCosaMas();
}

Mediante el operador ternario podemos incluir varias instrucciones usando funciones anónimas:


condicion
? (function(){ hazAlgo(); hazOtraCosa();})()
: (function(){ hazUnaCosa(); hazOtraCosaMas();})();

Usando un ejemplo de código real, podría ser así:


hasClassName(capa, clase)
? (function(){ removeClassName(capa, clase); enlace.title = 'Ocultar';})()
: (function(){ addClassName(capa, clase); enlace.title = 'Mostrar';})();

Sin comentarios

Sí Flash ya es de por sí bastante problemático en cuanto a accesibilidad se refiere, en Firefox tiene una dificultad añadida: no se puede acceder a su contenido mediante teclado. Para navegar por los elementos de un flash en Firefox necesitamos clicar el flash. Una vez que hemos entrado ya no podemos salir usando el teclado, la tabulación queda atrapada en el flash. La buena noticia es que si hemos podido entrar en el flash, se supone que sólo hemos podido hacerlo mediante ratón, por lo que también se supone que también podremos salir del flash usando el ratón, a no ser que justamente decida fallar en ese preciso momento. En cualquier caso, este comportamiento de Flash en Firefox hace que sea dependiente de dispositivo.

No ocurre lo mismo en Internet Explorer, en el que sí podemos entrar y salir del Flash mediante teclado. Podemos imitar el comportamiento de Flash en Internet Explorer mediante Javascript y Actionscript. En el siguiente ejemplo tenemos un flash al que podemos acceder mediante teclado en Firefox, navegar por sus elementos y salir de él.

Para conseguir esto se han seguido los siguientes pasos:

  1. Dar un tabindex con valor 0 al object que contiene el flash.De esta manera conseguimos que pueda tener el foco en Firefox. El valor 0 permite que el objeto permanezca en el orden de tabulación en que aparece en la página, es decir, no se altera el orden de navegación de otros elementos. Debemos hacerlo mediante Javascript, porque sin él, podríamos entrar mediante teclado al flash pero no podríamos salir.
  2. Permitir la comunicación del Flash con Javascript.Para esto usamos el parámetro allowscriptaccess de Flash
    
    <param name="allowScriptAccess" value="always" />
    
  3. Desde Flash llamamos a la función Javascript encargada de establecer el tabindex, de esta manera, sólo si hay flash se establecerá un tabindex para el object.
  4. Añadimos para el primer y último elemento navegables del flash una función para el evento onblur (en actionscript llamado onKillFocus) encargada de llamar a la función Javascript que desenfoca el object.
    
    // primer elemento navegable
    bot_1.onKillFocus = function(newFocus){
       if(newFocus == bot_3){
          ExternalInterface.call('AccesibleFlash.desenfocaObject', 'test');
       }
    }
    // último elemento navegable
    bot_3.onKillFocus = function(newFocus){
       if(newFocus != bot_2){
          ExternalInterface.call('AccesibleFlash.desenfocaObject', 'test');
       }
    }
    
  5. Por último, para evitar el “click para activar” en Explorer, se ha usado el método de publicación dinámica del SWFObject.

Descargar todos los archivos del ejemplo, incluido el .fla, en formato .zip

Una buena parte del “cómo conseguirlo” surgió de una cabeza inquieta de mi antiguo curro y creo, que hasta aquí puedo y debo leer.

1 Comentario

Iteración implícita con Mootools

Por kcmr, el 16 de Febrero de 2009 en Javascript

Etiquetas:, ,

Como los amantes de jQuery sabrán, para acceder a cada uno de los elementos de un HTMLCollection con este framework no necesitamos utilizar un bucle for o un método each(), ya que la iteración se hace de forma implícita.

Ejemplo con jQuery:


$('a.clase').bind('click', function(ev){
   ev.preventDefault();
   alert('Hola mundo');
})

Hoy descubro vía The Blueprint, que Mootools también permite hacer esta iteración implícita característica de jQuery, de manera que podríamos resumir el primer ejemplo de código en el que se usa el método each(), en el segundo ejemplo algo más corto usando la iteración implícita.

Usando each() con Mootools:


$$('a.clase').each(function(el){
   el.addEvent('click', function(ev){
      ev.stop();
      alert('Hola mundo');
  })
})

Usando la iteración implícita:


$$('a.clase').addEvent('click', function(ev){
   ev.stop();
   alert('Hola mundo')
})

Más información

Mootools DOM selector tips

Sin comentarios

He encontrado este script para detectar si una fuente está disponible en un determinado navegador, que nos puede sacar de más de un apuro, por ejemplo, cuando decidimos correr el riesgo de usar Arial Narrow como fuente “casi de sistema”.

En la web no dejan claro el modo de uso. Para detectar una fuente en concreto, en este caso la Arial Narrow, se podría usar el siguiente código añadido al script:


function testFont(){
   var inst = new Detector();
   if(!(inst.test('Arial Narrow')[3])) // si la fuente no está disponible...
      {
         // añadimos una clase al body
         document.body.className = 'nonarrow';
      }
}

En la CSS tendríamos que añadir las reglas alternativas para los navegadores que no tienen la fuente disponible:


#menu{font-family: "Arial Narrow", arial, tahoma, helvetica, sans-serif; font-size: 1.3em;}
body.nonarrow #menu{font-size: 1.2em; word-spacing: -1px;} /* arréglelo como pueda */

Para los que usen jQuery acabo de descubrir otra solución basada sólo en Javascript.

Información relacionada:

Sin comentarios