Uninstallme

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

Internet Explorer 8 usará Webkit como motor de renderizado

Por kcmr, el 28 de Diciembre de 2008 en Navegadores

Etiquetas:

Pasado el día de las inocentadas, debo advertir que este post contiene un 25% de verdad y un 25% de afirmaciones sacadas fuera de contexto. El resto es completamente falso :P

Los que nos dedicamos a esto de la maquetación estamos de enhorabuena con la noticia que se hacía pública ayer en el blog de IE de MSDN, y es que Microsoft pone fin a 13 años de “maltrato” a los estándares web, apostando por Webkit como motor de renderizado para el futuro Internet Explorer 8, que se lanzará finalmente a mediados del 2009.

Los rumores sobre la adopción de Webkit para Internet Explorer 8, comenzaban hace algo más de un mes, durante una conferencia en Australia, en la que Steve Ballmer, CEO de Microsoft, afirmaba estar interesado en el Open Source, y más concrétamente en Webkit.

Finalmente se ha confirmado que Internet Explorer mantendrá su interfaz propietaria y usará Webkit como motor de renderizado:

Each browser will have its own proprietary interface, unique set of features, but at least the rendering engine will be essentially the same.

No es la primera vez que algo así ocurre en la historia de los navegadores. Netscape tuvo una iniciativa parecida con su Netscape 6, con el que se saltaron la versión 5 apostando por una renovación completa y el uso de Gecko como nuevo motor de renderizado.

Aunque la noticia es esperanzadora, la lentísima actualización a la versión 7 por parte de los usuarios de Explorer y el desatino por parte de Microsoft al usar Internet Explorer 6 como navegador para la próxima generación de móviles basados en Windows Mobile, hacen que lamentablemente, tengamos que ver el desestancamiento en la implementación de nuevos estándares web como un futuro lejano.

1 Comentario

En Mocilla Developer Center he encontrado un método cuya existencia desconocía, pero que puede ser de gran utilidad. Se trata del método click, que ejecuta el evento onclick sobre elementos input (botones), checkboxes y radio buttons. En navegadores no basados en Gecko también ejecuta el evento onclick sobre enlaces.

Utilizando este método podemos conseguir de una manera sencilla que un formulario se envíe cuando un campo de texto pierda el foco, por poner un ejemplo.

Su uso es igual al de focus: elemento.click()

Más información

Sin comentarios

En mis últimos trasteos con el blog, he incorporado un “autocompletado” para el formulario de búsqueda. (Utilizo el término autocompletado porque es el más común, aunque yo simplemente lo llamaría resultados de búsqueda instantáneos.)

El funcionamiento se basa en hacer una petición AJAX para la consulta que estamos escribiendo en el campo de búsqueda cada vez que se pulse una tecla, a partir de 3 caracteres escritos. El resultado de esto es una lista que se va actualizando mientras escribimos, con las entradas que coinciden con nuestra búsqueda, con lo que, deseáblemente, los resultados se muestran de forma predictiva.

Ventajas de este sistema:

  • La obtención de resultados es mucho más rápida que si tuviéramos que cargar la página completa.
  • La aparición de la lista de resultados mientras se escribe, puede ahorrar la escritura del literal completo de búsqueda.

Inconvenientes:

  • Los usuarios se quedan sin la posibilidad de agregar la página de resultados a sus marcadores, volver mediante el botón del navegador a una consulta anterior, etc.
  • La página independiente de resultados de búsqueda nos ha quedado un poco desangelada.
  • Las actualizaciones dinámicas de contenido suponen un problema para algunos usuarios como los de lectores de pantalla.

Soluciones a los inconvenientes.

Pérdida de funcionalidad de la interfaz del navegador.

Este problema ha quedado sin resolver, aunque no afirmo que sea insalvable. Yo no conozco la solución.

Un usuario experimentado podría buscar la url de la petición AJAX e introducirla diréctamente en su navegador, o simplemente desactivar Javascript para obtener el comportamiento normal del formulario de búsqueda.

Página independiente de resultados.

Aunque esta página ha quedado bastante triste, se ha procurado que siga teniendo sentido por sí misma al sacarla del contexto para el que está diseñada (la caja de resultados dinámica.)

Para ello se han añadido varios textos ocultos al encabezado visible “Resultados de búsqueda”. Uno contiene los términos de búsqueda y otro el nombre del sitio en el que se ha realizado la búsqueda, de manera que si un usuario llegara a esta página sin haber pasado por el buscador, seguiría teniendo una referencia u orientación general sobre el contenido encontrado.

Por otra parte, se han seguido los principios del Javascript no intrusivo haciendo que los elementos que sólo tienen sentido con Javascript habilitado o que existen solamente para ejecutar una funcionalidad Javascript, no estén en el código HTML, sino que se generen también con Javascript. Para ello se ha reemplazado el enlace que aparece en la página de resultados a la página principal de este sitio, por el botón de cerrar que aparece en la caja de resultados.

Contenidos dinámicos VS lectores de pantalla.

Como comentaba en un post anterior, los usuarios de lectores de pantalla tienen dificultades para enterarse de las actualizaciones dinámicas de contenido mediante Javascript. En primer lugar no pueden apreciar visualmente los cambios, y en segundo lugar, los lectores de pantalla leen el contenido de la página de manera lineal, a partir de una “captura del DOM” (buffer virtual) que guardan al cargar la página.

Esto último supone, que mientras el contenido ha cambiado, el lector de pantalla sigue usando una versión no actualizada del DOM. En las últimas versiones del lector de pantalla JAWS, este problema se ha solucionado parcialmente refrescando el buffer virtual cada cierto tiempo para evitar que se use una versión desactualizada de la página. Aun así, la aparición o modificación de contenidos sigue resultando un problema, ya que, aunque el lector de pantalla actualice el buffer virtual, el usuario no tiene forma de saber automáticamente que el contenido ha cambiado o dónde se ha producido esa actualización de contenido.

Una de las medidas más efectivas para solucionar este problema, o al menos minimizarlo, consiste simplemente en llevar el foco a la capa en la que se generan los resultados de búsqueda, que por otra parte, y por razones de posicionamiento CSS, no aparece inmediátamente después del formulario de búsqueda, sino al final del documento. Para ello simplemente le hemos asignado un valor negativo (-1) al atributo tabindex, para que pueda recibir el foco mediante Javascript (elemento.focus();) pero no aparezca en el orden natural de tabulación de la página.

El atributo tabindex no valida en elementos que no sean campos de formulario o enlaces, por lo que se ha añadido mediante Javascript.

Con esto conseguimos que al desenfocar el campo de búsqueda (evento onblur), la capa con los datos actualizados reciba inmediátamente el foco y pueda ser leída a continuación.

WAI-ARIA para los más avanzados.

La solución de llevar el foco al elemento actualizado, resulta efectiva en Internet Explorer (6 y 7) usando JAWS y NVDA, pero para los navegadores que actualmente soportan WAI-ARIA (Firefox 2 y superiores y Opera), hemos añadido unos cuantos atributos que informan además, sobre la cantidad de contenido que se actualizará en un área dinámica, la prioridad con que el lector de pantalla debe anunciar la actualización o el papel que cumple el área actualizada en el documento (es un contenido independiente, complementario, navegación, etc.)

Para conocer una lista de las posibilidades de WAI-ARIA, recomiendo echarle un vistazo a los ejemplos de ARIA que publican en iCITA.

Después de varias combinaciones y pruebas con JAWS 9, NVDA y el plugin para Firefox, Firevox, he decidio usar las siguientes propiedades y atributos para la capa de los resultados:


'aria-live': 'assertive',
'aria-relevant': 'all',
'aria-atomic': 'true'

También tengo que comentar, que el lector de pantalla con el que he obtenido unos resultados más parecidos a los esperados, ha sido el lector gratuito NVDA.

Más información:

3 Comentarios

Una buena forma de evitar errores del usuario al rellenar formularios, es no dar lugar a que se produzcan y uno de los casos en los que esto es posible, es el de los típicos formularios que solicitan un número de cuenta bancaria.

La siguiente función usada con el evento onkeydown en campos de texto, comprueba que el caracter introducido sea la tecla tabulador o delete, cualquier número del 0 al 9 en el teclado normal, cualquier número del 0 al 9 en el teclado numérico, la tecla control o F5.


function esValorNumerico(event){
	if(!event) event = event || window.event;
	return (
		(event.keyCode > 7 && event.keyCode < 10)       // delete (8) o tabulador (9)
		|| (event.keyCode > 47 && event.keyCode < 60)   // números del teclado
		|| (event.keyCode > 95 && event.keyCode < 106)  // números del teclado numérico
		|| event.keyCode == 17   // Ctrl
		|| event.keyCode == 116  // F5
	)
}

Evitaríamos la introducción de cualquier caracter que no sea uno de los especificados, devolviendo false si la condición no se cumple.


inputs[i].onkeydown = function(event){
	if(!esValorNumerico(event)) return false;
}

¿Por qué con el evento onkeydown y no con onkeypress?

Por suerte, onkeydown funciona igual en todos los navegadores. Onkeypress sin embargo, devuelve 0 como keyCode para las teclas especiales, entre las que se encuentran los números, además de presentar diferencias importantes de funcionamiento entre Internet Explorer y el resto de navegadores.

Por cierto, con este problemilla he tenido la ocasión de comprobar que los códigos que se pueden encontrar por Internet para realizar esta acción son bastante prehistóricos (optimizados para Netscape 4). ¿Tendrán algo que ver los frameworks Javascript…?

Más información

Sin comentarios

Si queremos (deberíamos) hacer una tabla accesible, podemos hacer uso del atributo abbr de los encabezados de tabla (<TH>). Este atributo puede servir a dos propósitos complétamente distintos.

Abreviar contenidos largos en celdas

Muchas veces, se piensa que el uso de este atributo cumple la misma función que la etiqueta <abbr> de HTML para mostrar la forma extendidida de una abreviatura o abreviación, sin embargo, su uso en encabezados de tabla, aunque también puede cumplir este objetivo, está concebido justamente para el contrario. En la traducción de la especificación de HTML 4.01 de html.conclase.net, podemos encontrar el siguiente fragmento:

Este atributo debería usarse para proporcionar una forma abreviada del contenido de la celda; los agentes de usuario pueden representar esta forma abreviada en lugar del contenido de la celda cuando sea apropiado. Los nombres abreviados deberían ser cortos, ya que los agentes de usuario pueden representarlos repetidas veces. Por ejemplo, los sintetizadores de voz pueden representar los encabezados abreviados relacionados con una celda en particular antes de representar el contenido de esa celda.

En este ejemplo de código extraído de 456 Berea Street, podemos ver cómo se ha usado el atributo abbr para proporcionar una forma abreviada de cada encabezado:


<table summary="The number of employees and the foundation year of some imaginary companies.">
    <caption>Table 1: Company data</caption>
        <tr>
            <th abbr="Company">Company Name</th>
            <th abbr="Employees">Number of Employees</th>
            <th abbr="Founded">Foundation Year</th>
    </tr>

Expandir formas abreviadas en celdas

Otro caso en el que necesitaremos usarlo, es cuando el encabezado de tabla ya está abreviado. Un ejemplo podría ser el de los días de la semana abreviados mediate sus iniciales (L, M, X, J, V, S, D), en el que el uso del atributo abbr serviría para mostrar la forma extendida (Lunes, Martes, etc.)

En este ejemplo extraído de Dive Into Accessibility, podemos ver este otro uso del atributo abbr:


<tr>
    <th abbr="Sunday" align="center"><span class="calendar">Sun</span></th>
    <th abbr="Monday" align="center"><span class="calendar">Mon</span></th>
    <th abbr="Tuesday" align="center"><span class="calendar">Tue</span></th>
    <th abbr="Wednesday" align="center"><span class="calendar">Wed</span></th>
    [...]
</tr>

En mi opinión, raras veces necesitaremos usar este atributo, a no ser que tengamos un encabezado de tabla muy largo y su repetición continua pueda resultar una molestia.

Cuando lo usemos con el propósito contrario (mostrar una forma extendida), deberemos asegurarnos de que es realmente necesario y no estamos causando una molestia proporcionando una forma larga para un encabezado abreviado, si este ya resulta suficiéntemente claro por sí mismo.

Sin comentarios

  • Garantizar el funcionamiento de las aplicaciones Web independientemente del dispositivo, sistema operativo o navegador con que se acceda a ellas.
  • Evitar el uso de tecnologías propietarias con la consecuente creación de múltiples versiones.
  • Garantizar la compatibilidad hacia adelante y favorecer la compatibilidad hacia atrás.

Todo esto tiene los siguiente beneficios:

  • Menor coste de mantenimiento (una sola versión)
  • Se mejora la accesibilidad favoreciendo el acceso universal.
  • Se llega a un mayor número de usuarios.

Parece que a estas alturas, después de que la mayoría hayamos aceptado y promovido el uso de estándares Web, se hace necesario recordar para qué y por qué surgieron, ya que cuando aparece en escena el navegador o móvil de moda, algunos no dudan en crear aplicaciones que funcionarán sólo en estos dispositivos y cuya clave para ser compatible con otros, dependía simplemente del uso de estándares.

Parece que no hemos aprendido nada y, como sucedió durante la guerra de navegadores, volvemos a cometer los mismos errores utilizando las extensiones no estándar que los fabricantes de navegadores, tanto los “buenos” como los que van un paso por detrás, se empeñan en seguir implementando.

Creando aplicaciones específicas para uno u otro navegador, o frameworks de desarrollo para el iPhone, estamos favoreciendo la creación de múltiples versiones y una nueva guerra de navegadores.

Es simple, ¿por qué hacerlo para uno pudiendo hacerlo para todos?

Más información

¿Qué son los estándares web y por qué debería usarlos? en The Web Standards Project

4 Comentarios

En 61924 (sí, este parece ser el nombre del sitio) he descubierto un pequeño truco realmente sencillo, para utilizar la compresión Gzip en archivos Javascript y CSS sin utilizar PHP.

Para ello necesitamos, además de un servidor Apache, un compresor de archivos capaz de comprimir en formato Gzip, como 7zip, y añadir unas líneas en el .htaccess mediante las que indicamos que los archivos con la extensión indicada, utilizan este tipo de compresión.

Simplemente comprimimos el archivo que deseemos en formato .gzip y le damos como nombre de extensión de archivo .jgz en el caso de Javascript o .cgz en el caso de CSS.

Enlazamos al nuevo archivo en el HTML y añadimos estas líneas en el .htaccess


# Compressed javascript files
AddEncoding x-gzip .jgz
AddType application/x-javascript .jgz

# Compressed css files
AddEncoding x-gzip .cgz
AddType text/css .cgz

He hecho la prueba con esta web comprimiendo Mootools y estos son los resultados.

Antes de comprimir (63 Kb)

Captura de Firebug mostrando el tamaño de archivo antes de la compresión

Y después de comprimir (19 Kb)

Captura de Firebug mostrando el tamaño de archivo después de la compresión

Una técnica que merece la pena tener en cuenta si estás usando librerías Javascript pesadas.

6 Comentarios

Como los usuarios de Wordpress sabemos, este se empeña en darnos el nombre de usuario “admin” y no ofrecernos otra forma de cambiarlo que modificar diréctamente ese valor en la base de datos o bien crear otro usuario. En Ayuda Wordpress nos explican cómo cambiar el nombre de usuario modificándolo en la base de datos.

Si sólo queremos cambiar el literal “admin” sin preocuparnos de nada más, podemos hacerlo mediante el archivo my-hacks.php, que tendrá que estar en el directorio raíz de Wordpress, al mismo nivel que config.php, por poner un ejemplo.

Para ello utilizamos una función que se encarga de reemplazar el literal “admin” por el que queramos e indicamos dónde queremos que se ejecute esa función, por ejemplo, en el autor de la entrada “the_author” o en el autor de un comentario “get_comment_author”

El código sería este:


<?php
function replaceAdmin($content = '') {
return str_replace('admin', 'Pepe', $content);
}

add_filter('get_comment_author','replaceAdmin');
add_filter('the_author','replaceAdmin');
?>

Más información

Sin comentarios

Hace cosa de un mes publicaba otra forma de limpiar flotaciones y explicaba las ventajas de este método respecto a otros que se basan en el uso de hacks y ponen en peligro la compatibilidad hacia adelante. Pues bien, podía ser todavía más simple e indoloro.

Código CSS para la clase “clearfix”


.clearfix:after{content: ""; display: block; clear: both; height: 0; visibility: hidden;}
.clearfix{min-height: 0; height: 1%;}

Con el uso de min-height, atacamos a Internet Explorer 7 sin causar daños colaterales y con height 1% hacemos lo mismo con Explorer 6.

Demostración de clase “clearfix”.

Sin comentarios

Los rollovers de imágenes con javascript casi han pasado a la historia desde que podemos hacerlo de manera mucho más fácil y limpia con CSS, pero para los casos en los que, por la razón que sea, sea necesario que la imagen del rollover esté como elemento <img> en el código HTML, podemos conseguirlo utilizando sólo CSS.

El único requisito para que el rollover funcione en Internet Explorer 6, es que la imagen esté contenida en un enlace. En el caso de que la imagen sea un botón de tipo image, necesitaremos añadir una clase por Javascript, ya que Explorer 6 ignora el :hover sobre cualquier elemento que no sea un enlace.

El principal inconveniente de los rollovers con Javascript es que necesitamos dos imágenes para cada estado. Con esta técnica, usamos una sola imagen con sus dos estados, como lo haríamos con un rollover “normal” con CSS.

Imagen usada para el rollover:

La técnica se basa en conseguir un efecto “clip” mediante el uso de overflow: hidden. Para ello metemos la imagen en un elemento <span> al que damos el ancho y alto del área visible de cada estado de la imagen. En el ejemplo 22 píxeles. Damos display block y posición relativa para que Internet Explorer sea feliz (en otros navegadores no es necesaria la posición relativa)

Por último, damos al enlace en estado hover, posición relativa y una posición negativa igual a la altura de la imagen.  En este caso no es necesario dejar un margen en blanco entre ambos estados de la imagen para prevenir que al aumentar el tamaño de texto de la página se vea parte de la imagen para el estado hover, como ocurre con los navegadores que no hacen zoom (Firefox 2, Google Chrome, Internet Explorer 6) y los rollovers con CSS mediante imágenes de fondo, ya que que podremos aplicar dimensiones mediante CSS diréctamente a la imagen, permitiendo que se dimensione al aumentar el tamaño de texto.

El código HTML utilizado sería el siguiente:


<span class="img-rollover">
<a href="#"><img alt="A" src="boton-a.png" /></a>
</span>

Y el código CSS:


span.img-rollover{ width: 22px; height: 22px; overflow: hidden; display: block; position: relative; }
span.img-rollover a:hover{ top: -22px; position: relative;}

El resultado:

Técnica inspirada en el botón de buscar de The Man in Blue

7 Comentarios