2011/03/23

Usando imágenes para dar estilo a los elementos III. Usando imágenes

En el primer capítulo, hemos visto cómo usar sprites para crear estilos más atractivos, pero los sprites tienen pegas como son que se pueden ver fragmentos de otros sprites si nos nos andamos con cuidado y que hay que organizar muy bien la imagen de los sprites dejando mucho espacio alrededor y mucho espacio = imagen más grande = más lento. Si pudiéramos recortar la imagen de los sprites y quedarnos con lo que nos interesa... espera... que sí que se puede!

Se nos va a complicar un poco el CSS, pero podemos definir la imagen de los sprites como nos de la gana mezclando sprites de cualquier tamaño en cualquier sitio sin preocuparnos de que se vea lo que no debe y optimizando la imagen para que no queden espacios vacíos.

El secreto es usar la propiedad CSS2 "clip" que permite definir un rectángulo de recorte de la imagen que se diga.

Los sprites tradicionales, tendríamos que hacerlos así:

#first:before {
    content: "";
    float: left;
    width: 15px; height: 15px;
    margin: 4px 5px 0 0;
    background: url(sprite.png) -15px 0;
}
Pero con la nueva técnica se podrían hacer de la siguiente manera:
#second {
  position: relative;
  padding-left: 20px;
  background-image: expression(this.runtimeStyle.backgroundImage="none",this.innerHTML = '<img alt="" src="sprite.png">'+this.innerHTML);
}
#second:before,
#second img {
  content: url(sprite.png);
  position: absolute;
  top: 3px;
  clip: rect(0 30px 15px 15px);
  left: -15px; /* to offset the clip value */
  _left: -35px; /* some massaging for IE 6 */
}
Vale, es más compleja, pero hace lo que debe. Vamos a verlo en más detalle.
Lo primero, es definir el estilo base, dejando espacio a la izquierda para colocar el icono con el "padding-left: 20px". El "position:relative" es necesario para hacer que funcione la segunda parte.

Después, se aplica la pseudo-clase ":before" que es donde se muestra el sprite en sí con la propiedad "content" que cargaría tooooda la imagen. Acto seguido, la recorta con "clip" y la coloca en el (0,0) con el "top" y el "left"... es decir, en "top" está la -Y del origen vertical del sprite (en el ejemplo no es necesario) y "left" el -X del origen horizontal del sprite ya que la imagen tiene los sprites en "horizontal". El "position: absolute" es necesario porque "clip" solo funciona con coordenadas absolutas.

Vale, ahora vienen las chapuzas para que IE6/7 funcionen como deberían haberlo hecho. la primera es la expression que inyecta el código de la <img> de los sprites, la segunda, es aplicarle el estilo a la imagen del elemento con "#second img" y la tercera el usar el css hack "_left" que no entiende nadie salvo IE6 para colocar el sprite donde debe.

Ventajas
  1. Permite optimizar la imagen de los sprites y organizarla como nos de la gana.
  2. Permite imprimir correctamente. Al no ser un background, se va a imprimir. En el caso de la técnica clásica de sprites, si se imprime la página, los sprites no se imprimirían salvo que se especifique "imprimir background" con el riesgo de que se imprima TODO.
  3. Accesible. Compatible con todos los métodos de accesibilidad y visualización de alto contraste.
  4. Funciona en IE 6, 7, 8 y 9. Sorprendente, verdad?
Inconvenientes. Hay que escribir más... no es realmente un inconveniente, pero todos hemos nacido cansados, verdad?

No hay comentarios:

Publicar un comentario