Abrir enlaces externos en nueva ventana añadiendo class external y _blank target al vuelo con jQuery

Hace tiempo (2009 y como pasa de rápido…) hablábamos de esto mismo en _blank, rel=”external” y una solución jQuery para abrir enlace en nueva ventana. Ahora traigo una revisión del snippet con esa misma funcionalidad pero un poco más completa y optimziada.

Código jQuery

jQuery(document).ready(function($) { 	
 
	//open external links in new window
	$('a:not([href^="http://aurea.es"]):not([href^="#"]):not([href^="/"])').addClass('external');
	$('a[class="external"]').click(function(){ $(this).attr('target','_blank'); });
 
});

Explicación

  1. Comenzamos el mítico método ready de jQuery, encargado de comprobar si el DOM esta cargado y preparado para usarse. Tengamos en cuenta que deben estar todos los tags de enlaces ya descargados en el navegador para luego lanzar las operaciones sobre ellos.
  2. A continuación hacemos 3 comprobaciones basadas en el atributo “href”. Que el link no comience con el “dominio del sitio web” (link absoluto), que no comience por “#” (link ancla), y que no comience por “/” (link relativo). A todos los enlaces que cumplen esto se les añade la clase “external”, ejemplo: class="external".
  3. Una vez tenemos identificados todos los enlaces externos, ya solo queda preparar un evento .click() que añada el atributo target con valor blank (nueva ventana/tab) cuando el evento se dispare.

Acerca del Optimismo digital

Recientemente y vía WeblogsSL pude participar en el diseño y desarrollo de una publicación cuya temática me ha llamado la atención: optimismodigital.com

En su Manifiesto podemos leer:

Pensamos que el fenómeno de la digitalización de la sociedad, las industrias y el mundo no solo es inevitable sino que además es POSITIVO, DIVERTIDO, APASIONANTE y LLENO DE OPORTUNIDADES. Nuestra actitud ante esta nueva era debe de ser de CURIOSIDAD, EXPERIMENTACIÓN y de DISFRUTE.

No podría expresarlo de mejor forma, la idea es sentirnos optimistas ante la era digital en la que ya estamos inmersos :)

Los artículos que se van publicando son acertadísimos, y para comenzar ya han posteado gente de Google, Yahoo, Banco Popular, INGDirect, FXInteractive, BuyVip, etc.
Me encanta lo que estoy leyendo, os dejo únicamente 3 joyitas:

El Almacén de la Ilusión de Coca-Cola

Familiares, amigos, o simplemente aquellos que me seguís por el blog, quizás recordéis mi proyecto truequi.com, una plataforma de intercambio de objetos.

Pues bien, por aquí creemos que la ilusión es capaz de mover el mundo. Así que para esta Navidad vamos a ponerla en marcha entre todos, porque pensamos que la ilusión no se crea ni se destruye, se intercambia.

Y es por eso que nace en España el Almacén de la Ilusión. Partiendo de una gran iniciativa de Coca-Cola y tomando como base truequi, junto con el trabajo de grandísimos profesionales como Paco, Pilar, Carmen, Marie-la, Sertxu (equipo digital de Coca-Cola), la gente de Genetsis (infraestructura, servidores), Correos, Chonoexpress…, y luego estaba Marcos y la gente de Q-Interactiva, Israel y yo mismo que hemos dado forma y vida al sitio web. Un montón de gente persiguiendo un mismo objetivo, y la verdad es que nos hemos entendido muy bien desde el primer momento. Al final ya parecía aquello una gran familia :)

¡¡En el Almacén hay sitio para todo!! Puedes aportar tus ilusiones, aquellos artículos que han formado parte de tu vida y pienses que ahora pueden hacer feliz a otra persona. A cambio de subir tus ilusiones podrás escoger otras de personas que como tú quieran compartir las suyas.
Actualmente ya hay libros, películas, música, videojuegos, y otros objetos curiosos.

Y la cosa no acaba aquí, gracias a un acuerdo alcanzado entre Coca-Cola y Correos España, los 40.000 primeros envíos serán gratuitos. Vamos, que debido al amplio margen financiado todos podremos enviar y recibir nuestros regalos sin coste alguno.

Con todo esto se aprovecha la sinergia entre dos grandes empresas, como Coca-Cola y Correos, con gran capacidad para generar ilusión y hacer realidad el envío de paquetes en unas fechas marcadas por el gran incremento de actividad postal.

Para seros sinceros… no recuerdo una iniciativa tan bonita y valiente como esta en los 12 años que he vivido Internet. Pienso que toda España puede sentirse orgullosa de participar en ello :)

Así que toca olvidar por un momento la crisis, en el Almacén de la Ilusión el dinero no tiene cabida, solamente la ilusión de artículos que puedas ofrecer y recibir ;)

Bienvenidos al Almacén de la Ilusión.

(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)

Adios IFRAME, hola OBJECT

Cuando necesitamos incluir un objeto HTML externo incrustado en una página podemos recurrir al tag IFRAME.
Si el objeto que necesitamos incrustar es un SWF se suele recurrir a OBJECT y EMBED.

Antes de seguir, es bueno recordar la historia de los elementos IMG, EMBED y OBJECT.

OBJECT como sustituto de IFRAME

Con IFRAME podemos embeber un tipo de documento HTML. Pero si atendemos a la definición de OBJECT veremos que podemos embeber varios tipos de documento como: HTML, SWF, VIDEO, IMAGEN (ver ejemplos).
Teniendo en cuenta lo anterior, IFRAME puede verse como un TAG redundante.

Por otro lado en la versión XHTML Strict, el DTD no admite el tag IFRAME. Al fin y al cabo forma parte del pasado y la W3C siempre ha recomendado el uso de un OBJECT para incrustar los diferentes documentos, tanto si es vídeo, como imagen, como una página html.

Además hay que tener cuidado con IFRAME en Firefox, generado de forma dinámica podemos tener problemas (Bug 279048).

IE como de costumbre va contracorriente

Si usamos OBJECT en Internet Explorer, debemos tener en cuenta que no reconoce el atributo type:

<object type="text/html" ...

En su lugar tenemos que indicar un atributo classid:

<object classid="clsid:F08DF954-8592-11D1-B16A-00C0F0283628" ...

De todas formas con varias pruebas que hice he comprobado que el comportamiento es irregular en las diferentes versiones de la familia Internet Explorer (6, 7, 8, 9).
En cambio con IFRAME, Internet Explorer se maneja de maravilla :D todas las versiones interpretan y dan el mismo resultado.

IFRAME para IE, OBJECT para el resto

Al final pienso que la mejor opción cross-browser es mantener el IFRAME para la familia Internet Explorer y recuperar el OBJECT para el resto de navegadores (Firefox, Opera, Safari, Chrome).

Para hacer la bifurcación he recurrido a los comentarios condicionales de IE:

<!--[if IE]>
    <iframe src="page.htm">contenido alternativo</iframe>
<![endif]-->
<!--[if !IE]> <-->
    <object type="text/html" data="page.htm">contenido alternativo</object>
<!--> <![endif]-->

Conclusión, voy abrazando OBJECT mientras digo adiós al IFRAME a excepción de IE :P

CSS adaptado a cada navegador con PHP

Tener diferentes hojas de estilo dependiendo del navegador me parece algo horrible :( .  Pero si por algún motivo es necesario, podemos emplear una forma bastante fácil y limpia mediante PHP (Ref. Andrew Martin).

Para ello, (1) pondremos un CSS base que sea compatible para todos los navegadores y a continuación (2) haremos uso del array $_SERVER y del campo donde se cargan las cabeceras con información del navegador del usuario “HTTP_USER_AGENT”.

1. Código CSS base:

<link rel="stylesheet" href="base.css" type="text/css" />

2. Código PHP:

$browser = $_SERVER['HTTP_USER_AGENT'];	
if (preg_match('/MSIE.8/i', $browser)) { echo '<link rel="stylesheet" href="msie8.css" type="text/css" />'; } 
elseif (preg_match('/MSIE.7/i', $browser)) { echo '<link rel="stylesheet" href="msie7.css" type="text/css" />'; }
elseif (preg_match('/MSIE.6/i', $browser)) { echo '<link rel="stylesheet" href="msie6.css" type="text/css" />'; }
elseif (preg_match('/MSIE.9/i', $browser)) { echo '<link rel="stylesheet" href="msie9.css" type="text/css" />'; }
elseif (preg_match('/Firefox.2/i', $browser)) { echo '<link rel="stylesheet" href="firefox2.css" type="text/css" />'; }
elseif (preg_match('/Firefox.3.5/i', $browser)) { echo '<link rel="stylesheet" href="firefox35.css" type="text/css" />'; }
elseif (preg_match('/Firefox.3/i', $browser)) { echo '<link rel="stylesheet" href="firefox3.css" type="text/css" />'; }
elseif (preg_match('/Chrome/i', $browser)) { echo '<link rel="stylesheet" href="chrome.css" type="text/css" />'; }
elseif (preg_match('/Safari/i', $browser)) { echo '<link rel="stylesheet" href="safari.css" type="text/css" />'; }
elseif (preg_match('/Opera/i', $browser)) { echo '<link rel="stylesheet" href="opera.css" type="text/css" />'; }
else { echo '<link rel="stylesheet" href="unknown.css" type="text/css" />'; }

El código escribirá el link con la hoja de estilo correspondiente al navegador empleado por el usuario basándose en la comparación de cadenas.

Si lo que queremos es únicamente discernir la versión de MSIE, podemos también recurrir a los comentarios condicionales de Internet Explorer.

Para hacer las pruebas necesarias con los diferentes navegadores, podemos descargarlos o emularlos.

Consejos para Newsletter / e-mail

A continuación recopilo algunos consejos beneficiosos para evitar el Spam y mejorar la Usabilidad del Newsletter, en algunos casos también aplicables a un simple e-mail enviado al usuario. Read more »

Etiqueta PRE, desbordamiento en gmail y solución con nl2br o white-space

Me he encontrado con un problema que parece afectar exclusivamente a Gmail y que ocurre al recibir un mail que contiene la etiqueta pre.

La misión de esta etiqueta es pre-formatear su contenido, con lo cual mantiene en el texto los espacios en blanco, saltos de línea, etc. Y es justamente por esa razón por la que debemos tener mucho cuidado (no soy muy amigo de emplearla).

En Gmail, por ejemplo se producía un desbordamiento horizontal, donde salia el scroll y el texto continuaba a lo largo y ancho de la ventana :)

Como solución, sustituir pre por un simple div en conjunción con una de estas dos opciones para el contenido que albergará:

  • Formatear el contenido con PHP: Podemos ayudarnos de la función nl2br que insertará los saltos de línea.

    Ejemplo:

        nl2br('texto con formato');
  • Formatear el contenido con CSS: Podemos usar la regla white-space: pre; para simular el comportamiento de la etiqueta pre.

    Ejemplo:

        <div style="white-space: pre;">
            texto con formato
        </div>

Optimización de CSS; Nicole Sullivan nos enseña 5 errores típicos y 5 buenas maneras

Hace un tiempo escribí sobre algunas técnicas para poder optimizar nuestros códigos CSS. También mencionaba herramientas que puede facilitar nuestro trabajo de optimización: Firebug, PageSpeed, YSlow y YUI Compressor.

5 errores típicos

  • Un 42% de páginas no comprimen su contenido con GZIP.
  • Un 44% de páginas enlazan a más de 2 ficheros CSS.
  • Un 56% no sirven el CSS con cookies (o no la entiendo, o esta la veo complicada de evitar sin CDN).
  • Un 63% no minimiza sus ficheros con herramientas como YUI Compressor.
  • Un 21% de páginas tienen ficheros CSS con más de 100K de peso (esta es de escándalo).

Si en nuestros CSS sumamos: demasiada atomicidad, normas, duplicación, conflictos y lo aderezamos todo con algo de impredecibilidad, tendremos por resultado un enorme e incontrolable CSS.

5 buenas maneras

Lo que debemos evitar es:

1. La Atomicidad

Imaginemos una página Web como si fuera un coche. Para crear ese coche usamos piezas de lego, una a una las vamos posicionando hasta crear la figura del coche.

  • Con CSS básicamente hacemos lo mismo, podemos ir pieza a pieza posicionando y creando el sitio web. Y es justamente el planteamiento que debemos cambiar.
  • La idea es evitar pensar en pequeñas piezas (átomos) y pensar en objetos que se puedan reutilizar. De esta manera podemos por ejemplo crear con CSS una rueda del coche, que a su vez bastaría para simular las otras tres restantes.
  • Esto se podría considerar una evolución de la forma de pensar en el CSS.

2. Normas desfasadas

Que van acumulandose, que no se reutilizan, que son incrementales en el tiempo, muy especificas, etc.

3. Normas imprevisibles

Que no pueden ser reutilizadas y que son totalmente dependientes de su ubicación.

4. Guerras de especificidad

Nodos hijos de hijos de otros hijos, hacks, estilos con #ID que no pueden ser reutilizados, la sentencia !important no tiene cabida (si se usa bien la cascada), etc.

5. Duplicidad

Definir en numerosas ocasiones reglas como: margin, float, font-size, etc. Como solución tenemos:

(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)

PNG transparente e IE, el mítico problema…

Internet Explorer en su versión 6 y anteriores no soporta la transparencia del formato PNG.
Para solucionar este problema existen varias técnicas:

Todas ellas presentan pros y contras. Dependiendo del proyecto puede que venga mejor uno u otro, o que simplemente alguno no funcione por conflictos de JavaScript o misteriosas razones que solo las meigas de IE conocen. Así que la única solución es probar y probar… :(

A continuación voy a desarrollar la primera de ellas.

AlphaImageLoader

#logo  { 
	background-image: none;
	filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(
		src='http://..../logo.png', 
		sizingMethod='crop'
	); 
}

El primero de los pasos es indicar que no hay ningún fondo background-image: none;, a continuación usamos filter y la llamada Directx de Microsoft para cargar imágenes que incorporan factor alfa. En el parámetro src va la ruta absoluta al fichero png.

Conflicto con los enlaces

Con lo dicho anteriormente el PNG es mostrado con transparencia y sin errores, pero los enlaces no realizan el comportamiento adecuado si se encuentran en el interior de un elemento que tenga aplicado el filtro AlphaImageLoader.

Para solucionar este último problema podemos recurrir al siguiente código CSS:

#logo a { 
	position: relative; 
	z-index: 1; 
}

Cuando se aplica un filtro el elemento tiene una posición estática y esto presenta problemas en los enlaces, por ello se fuerza por medio de CSS a que los enlaces dispongan de una posición relativa y con z-index en una capa inferior.

Solo para Internet Explorer

Otros navegadores modernos (Firefox, Opera, Safari, Chrome) soportan perfectamente el formato PNG y su grado de transparencia, por tanto sería bueno pensar en ofrecer esta técnica únicamente cuando el usuario se encuentra navegando con Internet Explorer. Para lograrlo podemos recurrir a los comentarios condicionales:

<!--[if lt IE 7]><link rel="stylesheet" href="ie6.css" mce_href="ie6.css" type="text/css" media="screen" /><![endif]-->

Mediante este comentario condicional ubicado en el head podemos indicar que solo aquellos navegadores que sean inferiores al Internet Explorer 7 [if lt IE 7] se enlace el fichero de esitlo “ie6.css” que a su vez contiene los códigos comentados para esta técnica.

De esta forma:

  • No obligamos a que se interprete código propietario (no estándar) como el filtro AlphaImageLoader por parte de otro navegador que no sea IE6 o inferior.
  • El sitio Web será estándar y válido según el W3CValidator.
  • Reducimos el código CSS innecesario para otros navegadores y con ello logramos una mejor optimización.

Texto alternativo (alt) en casos especiales

El atributo alt de una imagen u otro elemento debe proporcionar un texto alternativo que contenga la información que se pretendía transmitir. No olvidemos que la información textual es la de mayor grado de accesibilidad.

Usar textos alternativos lógicos y coherentes

  • Si la imagen contiene texto, por ejemplo un número de teléfono, debemos transmitirlo completamente, alt="Teléfono: 000 000 000".
  • Si la imagen es un icono de error, el texto debe transmitir esa misma idea, podemos usar simplemente alt="error".
  • Si se trata de un icono “ZIP”, podemos usar algo como alt="fichero comprimido en ZIP".
  • En el caso de una fotografía podemos describir lo que vemos, alt="Asturias, tierra de altas montañas".
  • Si la imagen transmite acción, por ejemplo un enlace que tenga un icono de una impresora, debemos indicar dicha acción y no la descripción del icono, alt="imprimir".
  • Si una imagen transmite lo mismo que un texto contiguo, debemos dejar el texto alternativo vació para no caer en redundancias, alt="".

Las votaciones

Supongamos que tenemos el clásico sistema de votaciones con estrellas:
puntuación 4 de 5

Siguiendo las directrices de WCAG2 lo que podemos hacer es usar el atributo alt de la primera imagen para describir a todo el grupo e indicar la puntuación global. El resto de las imágenes que deberían estar situadas de forma contigua, tienen que tener alt="" vacio y no llevar ningún title, de esta forma son obviadas. Con ello se consigue que las ayudas técnicas (como por ejemplo lectores de pantalla) únicamente “lean” el texto alternativo de la primera imagen donde se da toda la información necesaria al usuario.

Ejemplo

<img src="star1.png" alt="puntuación 4 de 5" />
<img src="star2.png" alt="" />
<img src="star3.png" alt="" />
<img src="star4.png" alt="" />
<img src="star5.png" alt="" />

Los emoticonos

Se tiene que transmitir de forma textual el mismo sentimiento que el representado. Por ejemplo: Feliz alt="Feliz".

<img src="http://aurea.es/wp-includes/images/smilies/icon_smile.gif" alt="Feliz" />

Supongamos que en vez de una imagen usamos texto (ASCII). En este caso podemos marcar los emoticonos como abreviaturas (semánticamente podrían ser considerados así) y con el atributo title="sentimiento"
Por ejemplo: :-)

<abbr title="Feliz">:-)</abbr>