Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Ningún explorador quedará fuera: una estrategia para la adopción de HTML5
Brandon Satrom
Descargar el ejemplo de código
Hay mucho por qué entusiasmarse con HTML5. Con nuevo marcado, capacidades de CSS y API de JavaScript, el alcance de lo que es posible en la Web está creciendo a pasos agigantados. Agregue a eso la superioridad constante entre proveedores de exploradores y la lista de características emocionantes se amplía casi a diario. Desde compilaciones nocturnas a versiones de canal de dev y vistas previas de plataforma regulares, los exploradores están cambiando rápido y los desarrolladores web en todas partes no se quieren perder esta emocionante carrera.
Pero por mucho que la comunidad de desarrolladores y exploradores toquen el bombo publicitario al son de la fiebre del HTML5, la gran mayoría de los usuarios de la Web no usan las versiones más recientes de los exploradores que nosotros usamos. Si es un desarrollador web en una tienda de desarrollo de envergadura o una empresa con una gran base de usuarios, probablemente ya sabe esto. Incluso si está trabajando con una tienda pequeña o una startup que proporcione algún servicio a través de la Web, probablemente pasa mucho tiempo asegurándose de que su sitio pruebe tantos exploradores posibles como versiones de ellos haya.
Dada esta realidad, es fácil ver HTML5 no en términos de si está listo para usarse hoy, sino de si usted está listo para él. Por ejemplo, supongamos que creó una página con algunas de las nuevas etiquetas semánticas (como <header> y <article>), agregó algunas características nuevas de CSS (como el radio de borde y la sombra del cuadro) e incluso agregó un elemento <canvas> para obtener un logotipo HTML5 a su página.
En exploradores más nuevos como Internet Explorer 9, Firefox 4 y posterior, o Google Chrome, esto aparece ilustrado en la Figura 1. Pero si intenta cargar esta página en Internet Explorer 8 o inferior, verá algo más parecido a la Figura 2: una página totalmente dañada.
Figura 1 Página semántica con estilos y un elemento <canvas> de HTML5, como se ve en Internet Explorer 9
Figura 2 La misma página semántica como se ve en Internet Explorer 8 sin estilos y sin ningún <canvas>
No lo culparía si mirara todas las grandiosas características de HTML5 y, después de experimentar algo como esto, se dijera que el mejor curso fue esperar. Es fácil llegar a la conclusión de que, listo o no, HTML5 aún no está listo para usted o sus usuarios.
Antes de tomar la decisión de fijar una fecha en 2022 para echar otro vistazo a HTML5, le pido que lea el resto de este artículo. Mi objetivo este mes es ofrecerle estrategias prácticas para que pueda adoptar las tecnologías de HTML5 hoy sin terminar con el tipo de degradación sin gracia que aparece en la Figura 2. En este artículo, abarcaré:
- Detección de características frente al examen de agente de usuario
- Polyfill con JavaScript
- Degradación grácil
Estos tres temas deben decirle bastante de lo que necesita saber para crear sitios web para un espectro amplio de exploradores. Para cuando hayamos terminado, tendrá una sólida estrategia para adoptar tecnologías de HTML5 con confianza y sin retraso. También tendrá algunas herramientas que puede usar para mejorar progresivamente los sitios para exploradores más nuevos, mientras degrada grácilmente para otros.
La importancia de la detección de características
A fin de proporcionar experiencias estables y coherentes entre los exploradores, los desarrolladores a menudo deben tener cierta información acerca del explorador de un usuario. Históricamente, era común determinar esa información con JavaScript así:
var userAgent = navigator.userAgent;
if (userAgent.indexOf('MSIE') >= 0) {
console.log("Hello, IE user");
} else if (userAgent.indexOf('Firefox') >= 0) {
console.log("Hello, Firefox user");
} else if (userAgent.indexOf('Chrome') >= 0) {
console.log("Hello, Chrome user");
}
Esta técnica, conocida como examen de agente de usuario, se usa ampliamente para determinar qué explorador solicita su página. La lógica es que al conocer el explorador del usuario (Internet Explorer 7, por ejemplo), puede tomar decisiones de tiempo de ejecución acerca de cuáles características de su sitio habilitar o deshabilitar. El examen de agente de usuario equivale a decirle al explorador: “¿Quién eres?” (Para obtener un análisis en profundidad sobre el examen de agente de usuario y otras técnicas de detección, consulte bit.ly/mlgHHY.)
El problema con este enfoque es que se puede hacer que los exploradores mientan. La cadena de agente de usuario es una información que el usuario puede configurar y que realmente no proporciona una imagen cien por ciento precisa del explorador en cuestión. Lo que es más, ya que esta técnica se aceptó ampliamente, muchos proveedores de exploradores agregaron contenido adicional a sus propias cadenas de agente de usuario como una manera de lograr que los scripts saquen conclusiones incorrectas sobre qué explorador se estaba usando, para enredar la detección. Algunos exploradores ahora incluso incluyen una facilidad que permite que los usuarios cambien su cadena de agente de usuario con solo un par de clics.
Aunque el objetivo del examen de agente de usuario nunca fue conocer el explorador del usuario ni su versión. Y ciertamente no pretendía ofrecerle un camino para decirles a sus usuarios "vayan a descargar otro explorador" si usaban uno que a usted no le gustara, aunque algunos usen esa técnica. Los usuarios sí tienen una opción en el explorador que usan, pero nuestra responsabilidad como desarrolladores es proporcionar la experiencia más confiable y coherente, no imponerles una opinión de preferencia de explorador. El objetivo del agente de usuario siempre fue brindarle una imagen precisa de las capacidades o características que podría aprovechar dentro del explorador actual del usuario. El conocimiento del explorador mismo es solo un medio para esa información.
Hoy en día existen alternativas al examen de agente de usuario y una que está creciendo en popularidad (en parte gracias a jQuery y Modernizr) se llama detección de objeto o característica. Estos términos son, en su mayoría, intercambiables, pero me atendré a la “detección de características” para este artículo.
El objetivo de la detección de características es determinar si una característica o capacidad determinadas es compatible con el explorador actual del usuario. Si el examen de agente de usuario es como preguntarle al explorador “¿quién eres?”, la detección de características es como preguntarle “¿de qué eres capaz?”, una pregunta mucho más directa y una manera más confiable para proporcionar funciones condicionales a los usuarios. Es mucho más difícil que los usuarios y los exploradores finjan o informen erróneamente la compatibilidad de características, suponiendo que los scripts de la detección de características están implementados correctamente.
Detección manual de características
Entonces, ¿cómo es la detección de características en comparación al ejemplo de examen de agente de usuario? Para responder eso, echemos un vistazo a la corrección de los problemas que surgieron al ver mi página HTML5, Figura 1, en Internet Explorer 8 en lugar de Internet Explorer 9. El marcado para esta página aparece en la Figura 3.
Figure 3 Página con nuevo marcado semántico de HTML5
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My Awesome Site</title>
<style>
body { font-size: 16px; font-family: arial,helvetica,clean,sans-serif; }
header h1 { font-size: 36px; margin-bottom: 25px; }
article
{
background: lightblue;
margin-bottom: 10px;
padding: 5px;
border-radius: 10px;
box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.5);
}
article h1 { font-size: 12px; }
</style>
</head>
<body>
<header><h1>My Awesome Site</h1></header>
<article>
<header><h1>An Article</h1></header>
<p>Isn't this awesome?</p>
</article>
<canvas width="250" height="500"></canvas>
</body>
<script src="../js/html5CanvasLogo.js" type="text/javascript"></script>
</html>
Las diferencias entre Internet Explorer 9 e Internet Explorer 8, tal como se aprecia en las Figuras 1 y 2, son drásticas. Para los principiantes, mi página no tiene estilo en absoluto, como si el CSS para esta página no existiera. Lo que es más, me falta el elegante escudo HTML5 en la parte inferior de la página. Cada uno de estos problemas se puede corregir fácilmente y la detección de características es el primer paso para identificar el problema.
La causa de ambos problemas es sencilla: <header>, <article> y <canvas> no son elementos HTML válidos para Internet Explorer 8 y por tanto no puedo trabajar con ellos. Para resolver el problema de <canvas>, en lugar de usar el examen de agente de usuario para determinar qué explorador/versión se está usando, me gustaría preguntarle al explorador, a través de JavaScript, si el elemento <canvas> y sus API de JavaScript son compatibles. Mi comprobación de características para canvas presenta el siguiente aspecto:
!!document.createElement('canvas').getContext
Esta instrucción hace un par de cosas. Primero, usa doble negación (¡!) para forzar que los valores sin definir sean explícitamente falsos. Luego, crea manualmente un elementos canvas nuevo y lo adjunta a DOM. Finalmente, invoca getContext, una nueva función disponible para elementos <canvas> como una manera de manipular la API de Canvas a través de JavaScript. Si estoy usando Internet Explorer 9, esta instrucción se devolverá verdadera. Si estoy usando Internet Explorer 8, getContext se devolverá “sin definir”, lo cual mi doble negación forzará como falso.
Eso es detección de características en su aspecto más básico. Con esta instrucción y otras similares, ahora tengo una manera más confiable de consultar la compatibilidad de las características dentro del explorador. Para obtener más información sobre la detección manual de características, visite diveintohtml5.info/everything.html.
Uso de Modernizr para detección de características
La detección manual de características ciertamente es una mejora respecto del examen de agente de usuario, pero este enfoque todavía lo deja con la pesada carga de detectar la disponibilidad de una característica y decidir qué hacer si esa característica no existe. Y aunque el ejemplo de canvas era una sencillo que requería una línea de código, este no es el caso para cada característica que desee detectar, como tampoco es el mismo código de detección en todos los exploradores. Detectar compatibilidad para los módulos CSS3 que usé anteriormente (radio del borde y sombra del cuadro), por ejemplo, puede ser un poco más complejo.
Afortunadamente, Modernizr (modernizr.com) ofrece un mejor enfoque. Modernizr es una biblioteca de JavaScript que “… detecta la disponibilidad de implementaciones nativas para tecnologías web de última generación, es decir, características que nacen de las especificaciones HTML5 y CSS3”. Agregar una referencia a Modernizr en sus páginas suministra cuatro características principales:
- Una lista integral de características compatibles agregada de manera inteligente a su marcado, lo cual permite definiciones de CSS condicionales.
- Un objeto JavaScript que ayuda en la detección de características basadas en scripts.
- Todas las etiquetas nuevas de HTML5 al DOM en tiempo de ejecución, para el beneficio de Internet Explorer 8 y exploradores de Internet Explorer anteriores (más información sobre ello en un momento).
- Un cargador de script para cargar condicionalmente polyfills en sus páginas.
No analizaremos el primer elemento más a fondo en este artículo, aunque los animo a visitar modernizr.com y revisar la documentación sobre esto y el resto de las características.
El segundo elemento es la característica que ayuda a transformar esta línea de código:
!!document.createElement('canvas').getContext
En esta línea de código:
Modernizr.canvas
Esto devuelve un valor booleano que indica si el elemento canvas se admite en la página. Lo maravilloso acerca de usar Modernizr en vez de implementar su propia detección de características es que Modernizr es una biblioteca eficaz, bien probada y ampliada utilizada que se ocupa de la carga pesada por usted. Twitter, Google, Microsoft y una infinidad de otros usan Modernizr, y. usted también puede. Con la Actualización de herramientas de ASP.NET MVC 3 (lanzado en abril de 2011) Microsoft incluso incluye Modernizr desde un principio con las aplicaciones nuevas de ASP.NET MVC. Desde luego, todo lo que he logrado en este punto es detectar si el elemento <canvas> es compatible. No he dicho nada sobre qué hacer a continuación. Dado el conocimiento, a través de la detección de características, de que una característica está o no disponible para un explorador, un paso siguiente común es crear cierta lógica condicional que evite que determinado código se ejecute si una característica no existe o que ejecute una ruta alternativa, similar a esta:
if (Modernizr.canvas) {
// Execute canvas code here.
}
Agregar características a su sitio basado en la presencia de capacidades adicionales del explorador se conoce como “mejora progresiva”, ya que mejora la experiencia para un explorador más capaz. Al otro extremo del espectro se encuentra la “degradación grácil”, donde la ausencia de ciertas características no provoca el error del explorador, sino que presenta al usuario determinada característica disminuida o capacidad alternativa. En el caso de exploradores más antiguos, la degradación grácil no tiene que ser su opción predeterminada. En muchos casos, puede que ni siquiera sea su mejor opción. En su lugar, con la ayuda de Modernizr, a menudo puede usar uno de muchos polyfills del explorador disponibles para agregar características tipo HTML5 a explorados incompatibles.
¿Qué son los polyfills?
Según el sitio web de Modernizr, un polyfill son correcciones de compatibilidad (shim) de JavaScript que copia la API estándar para exploradores más antiguos”. “API estándar” se refiere a una tecnología o característica de HTML5, como canvas. Las “correcciones de compatibilidad (shim) de JavaScript” implican que puede cargar dinámicamente código o bibliotecas de JavaScript que imiten esas API en exploradores que no las admiten. Por ejemplo, un polyfill de ubicación geográfica agregaría el objeto de ubicación geográfica global al objeto navegador, así como también agregaría la función getCurrentPosition y el objeto de devolución de llamada “coordenadas”, todo según lo define la API de ubicación geográfica del World Wide Web Consortium (W3C). Como el polyfill imita una API estándar, puede desarrollar contra esa API a prueba del futuro para todos los exploradores, con el objetivo de eliminar el polyfill una vez que la compatibilidad alcance masa crítica. No se requiere trabajo adicional.
Al agregar una referencia a Modernizr en mi página, sí obtengo un beneficio de polyfill inmediato relacionado con el ejemplo en la Figura 3. La página resultante no posee estilo porque Internet Explorer 8 no reconoce etiquetas como <article> y <header>. Y como no las reconoció, no las agregó al DOM, que es cómo CSS selecciona los elementos para aplicarles estilo.
Cuando agrego una etiqueta <script> y hago una referencia a Modernizr a mi página, el resultado es una página con estilo, como en la Figura 4. Obtengo este beneficio porque Modernizr agrega manualmente todas las etiquetas de HTML5 nuevas al DOM mediante JavaScript (document.CreateElement(‘nav’)), lo cual permite que las etiquetas se seleccionen y se les aplique estilo con CSS.
Figura 4 Página de HTML5 en Internet Explorer 8, con la ayuda de Modernizr
Más allá de su uso para agregar compatibilidad para los nuevos elementos de HTML5 en Internet Explorer, la biblioteca Modernizr no proporciona ningún polyfill adicional de fábrica. Esos los proporciona usted mismo, ya sea desde sus propios scripts o desde la lista de opciones en constante aumento documentada en el sitio web de Modernizr. A contar de la versión 2.0, Modernizr proporciona un cargador de script condicional (basado en yepnope.js—yepnopejs.com) que lo ayuda a descargar bibliotecas de polyfill de manera asincrónica solo cuando es necesario. Usar Modernizr con una o más bibliotecas de polyfill que proporcionen características que necesita es una eficaz combinación.
Uso de polyfills para simular las funciones de HTML5
En el caso de canvas, puede usar compatibilidad de polyfill para Internet Explorer 8 y versiones anteriores con la ayuda de Modernizr y una biblioteca de JavaScript llamada excanvas, la cual agrega compatibilidad de canvas en el nivel de la API para Internet Explorer 6, Internet Explorer 7 e Internet Explorer 8. Puede descargar excanvas en bit.ly/bSgyNR y, después de agregarla a su carpeta de scripts, puede agregar algo de código a un bloque de script en su página, como se muestra en la Figura 5.
Figura 5 Uso de Modernizr para usar polyfill para la compatibilidad de canvas
Modernizr.load({
test: Modernizr.canvas,
nope: '../js/excanvas.js',
complete: function () {
Modernizr.load('../js/html5CanvasLogo.js');
}
}]);
Aquí estoy usando el cargador de script Modernizr para especificar tres cosas:
- Una expresión booleana que probar
- Una ruta a un script para cargar si la expresión se evalúa como falsa
- Una devolución de llamada para ejecutarse después de finalizada la carga del script o la comprobación
En el contexto de canvas, esto es todo lo que necesito para agregar un poco de inteligencia y polyfill a mi aplicación. Modernizr cargará excanvas.js de manera asincrónica solo para exploradores que no admiten canvas y que luego cargarán mi biblioteca de scripts para dibujar el logotipo de HTML5 en la página.
Miremos otro ejemplo para subrayar el valor de Modernizr. Es posible que aquellos de ustedes proclives a los detalles hayan notado que el sitio con estilo en la Figura 4 no es el mismo que la página original, como la arroja Internet Explorer 9 y como se muestra en la Figura 1. A la página, como se ve en Internet Explorer 8, le falta una sombra de cuadro y las esquinas redondeadas, y no pude transportar este maravilloso sitio sin ninguno de ellos, así que nuevamente apelaremos a Modernizr por ayuda.
Tal como con el canvas, Modernizr puede decirme que los módulos CSS3 no son compatibles, pero depende de mí proporcionar una biblioteca para aplicarles polyfill. Afortunadamente, existe una biblioteca denominada PIE (css3pie.com) que proporciona ambos módulos en una sola biblioteca.
Para agregar compatibilidad para radios de borde y sombras de cuadros, puedo agregar el código en la Figura 6 a mi script después de descargar PIE. Esta vez, probaré para ver si alguno de los módulos de radio de borde o de sombra de cuadro son compatibles (al contrario de suponer que ambos son siempre compatibles o no) y si alguno de ellos es incompatible, si carga PIE.js. de manera dinámica. Una vez finalizada la carga de PIE, ejecutaré jQuery para seleccionar todas mis etiquetas <article> y llamaré a la función PIE.attach, la cual agrega compatibilidad para los estilos de radio de borde y sombra de cuadro ya definidos en mi CSS. El resultado final se muestra en la Figura 7.
Figura 6 Uso de Modernizr y PIE para agregar compatibilidad de CSS3
Modernizr.load({
test: Modernizr.borderradius || Modernizr.boxshadow,
nope: '../js/PIE.js',
callback: function () {
$('article').each(function () {
PIE.attach(this);
});
}
});
Figura 7 Compatibilidad de CSS3 con Modernizr and PIE
Uso de polyfills para ayudar en la degradación grácil
Además de usar las técnicas de polyfill analizadas aquí, también puede aprovechar a Modernizr para ayudar en casos en que dese degradar grácilmente su aplicación, en contraposición a aplicar polyfill en otra biblioteca.
Digamos que tengo un control Bing Maps en una página web y deseo usar la ubicación geográfica (lo cual cubriremos a fondo en un próximo artículo) para hallar la ubicación actual del usuario y luego colocar esa ubicación como una chincheta en el control del mapa.
Aunque la ubicación geográfica se admite en versiones recientes de todos los exploradores, no se admite en exploradores más antiguos. También es un poco más complicado proporcionar compatibilidad con la API de ubicación geográfica puramente a través de JavaScript y, aunque sí existen polyfills para esta característica, he decidido degradar grácilmente mi aplicación. En casos en que el explorador del usuario no admite la ubicación geográfica, proporcionaré un formulario para ingresar la ubicación manualmente, la cual usaré a continuación para posicionar y pinchar el mapa.
Con Modernizr, es una simple llamada de carga a uno de los dos scripts que he creado, tal como se ilustra en la Figura 8. En este caso, estoy probando la propiedad de ubicación geográfica de Modernizr. Si es verdadera (“¡sí!”), cargaré mi script fullGeolocation.js, el cual usará la API de ubicación geográfica para hallar la ubicación (con mi permiso) y colocarla en un mapa, como se ilustra en la Figura 9. Si, por otra parte, el prueba resulta falsa (“no”), cargaré un script de reserva que muestra un formulario de dirección en mi página. Cuando el usuario envíe el formulario, usaré la dirección proporcionada para centrar y pinchar el mapa, tal como se ilustra en la Figura 10. De esta manera, mi página proporciona una gran experiencia a exploradores modernos, mientras que se degrada grácilmente en una alternativa razonable para otros más antiguos.
Figura 8 Uso de Modernizr para proporcionar degradación grácil
Modernizr.load({
test: Modernizr.geolocation,
yep: '../js/fullGeolocation.js',
nope: '../js/geolocationFallback.js'
});
Figure 9 Mapas con ubicación geográfica
Figura 10 Proporcionar compatibilidad de reserva con ubicación geográfica
Es fácil mirar algunas de las características avanzadas de HTML5 y, de cara a una base de usuarios grande aún en exploradores más antiguos, decidir que su sitio no está lo bastante listo para ellas. Pero existen excelentes soluciones ya disponibles que no solo ayudan en la degradación grácil, sino que además proporcionan la capacidad de traer al presente esos exploradores más antiguos para que los usuarios puedan experimentar HTML5 ahora mismo. En el curso de este artículo, ha visto que con la detección de características, Modernizr y polyfill, es posible adoptar HTML5 sin demora para el segmento siempre en aumento de sus usuarios con un explorador moderno, siempre que se tenga cuidado de no dejar al resto de su base de usuarios atrás.
Brandon Satrom trabaja como evangelista desarrollador de Microsoft en Austin, Texas. Tiene un blog en UserInexperience.com y lo puede encontrar en Twitter en twitter.com/BrandonSatrom.
Gracias a los siguientes expertos técnicos por su ayuda en la revisión de este artículo: Damian Edwards, Scott Hunter y Clark Sell