2011/03/24

Usando imágenes para dar estilo a los elementos IV. Hacks de background-image

Aunque ya hemos visto una forma óptima de tratar con sprites, aún se le puede sacar algo de jugo para determinados casos. Las secciones de este artículo se van a aplantear como si existieran las propiedades CSS de las que se habla.

Emulando background-crop.
Básicamente, es lo que hemos estado haciendo en el capítulo III de esta serie de posts. Podría ponerse simplificado, pero se perdería la posibilidad de hacerlos cross-browser. Merece la pena repasar el artículo.
Hay tímidos avances en incorporar esta funcionalidad como la de firefox con -moz-image-rect y la inclusión de image slices en el borrador para imágenes de CSS3 por lo que dentro de poco debería ser una característica de base en vez de una rareza.


Emulando multiple-background (CSS2.1)
Para navegadores medianamente actuales (es decir, IE8+) se puede aplicar esta técnica. La base de todo está en cómo se componen las capas de los pseudo-elementos :before y :after en un elemento HTML. Se puede ver cómo en el diagrama de la izquierda.

Así, se podría tener un fondo para el elemento, un fondo en el :before y otro en el :after, teniendo encima de todo el contenido del elemento, todo en ese orden de "abajo" a "arriba".

Un ejemplo de ésto funcionando creando un efecto además de tipo parallax, es el que se puede ver en el siguiente CSS.

Se supone que se tiene un elemento llamado #contenedor y dentro de él se va a situar before y after una imagen, cada una con su propio fondo.
#contenedor {
   position:relative;
   z-index:1; /* pone el orden correcto */
   background:#d3ff99 url(fondo-mas-profundo.png) -10% 0 repeat-x; /* el fondo de atrás del todo */
   min-width:200px; min-height:200px; padding:120px 200px 50px; /* esto es estético */
}
/* Estilos comunes de :before y :after */
#contenedor:before,
#contenedor:after {
   position:absolute;
   z-index:-1; /* pone el orden correcto */
   top:0; left:0; right:0; bottom:0;
   padding-top:100px; /* estético */
}
/* Estilos específicos de :before y :after */
#contenedor:before {
   content:url(imagen-1.png); /* El contenido es una imagen en este caso */
   padding-left:3%; text-align:left;
   background:transparent url(fondo-intermedio.png) 300% 0 repeat-x;
}
#contenedor:after {
   content:url(imagen-2.png); /* El contenido es una imagen en este caso */
   padding-right:3%;
   text-align:right;
   background:transparent url(fondo-primer-plano.png) 70% 0 repeat-x;
}
 
Emulando background-transform.
Combinando pseudo-elementos mediante :before con transformaciones transform de CSS3, se pueden hacer cosas como por ejemplo, rotar el icono de un acordeón al ser pulsado.

Evidentemente, IE 6, 7 y 8 no están invitados a esta fiesta aunque se podría currar algo con filtros, cosa que no voy a hacer en este momento.
.accordion a:before {
   content:"";
   float:left;
   width:16px;
   height:16px;
   margin:0 5px 0 0;
   background:url(sprite.png) no-repeat 0 0;
}
.accordion.open a:before {
   -webkit-transform:rotate(90deg);
   -moz-transform:rotate(90deg);
   -ms-transform:rotate(90deg);
   -o-transform:rotate(90deg);
   transform:rotate(90deg);
}
Emulando background-transform-mirror
Este es una tontería, pero el resultado es algo que más de una vez he tenido que hacer y que he tenido que recurrir a photoshop y similares.

En vez de rotar el elemento, se hace un transform: scaleX(-1) para que las sombras queden bien.

Para simular que se ha presionado el botón y que las sombras queden bien, se hace la transformación de escalado tanto en el eje X como en el Y con transform: scale(-1,-1)

El código CSS del ejemplo sería.

.prev a:before,
.next a:before {
   content:"";
   float:left;
   width:16px; height:16px; margin:0 5px 0 0; /* tamaños */
   background:url(sprite.png) no-repeat 0 0;
}
.next a:before {
   float:right; /* Lo coloca a la derecha */
   margin:0 0 0 5px;
   -webkit-transform:scaleX(-1);
   -moz-transform:scaleX(-1);
   -ms-transform:scaleX(-1);
   -o-transform:scaleX(-1);
   transform:scaleX(-1);
}

Como os habréis imaginado el IE8 (y anteriores) no están invitados a la fiesta.

Emulando background-position
CSS 2.1 limita el uso de background-position a desplazamientos desde los lados izquierdo y superior de la imagen, pero sin embargo es posible emular el posicionamiento a partir de los border derecho e inferior aplicando el fondo a un pseudo-elemento y luego desplazando dicho pseudo-elemento.

La base es la misma que en la técnica de multiple-background y el CSS quedaría así, considerando que es el elemento #contenedor al que se le quiere colocar el fondo a partir de la derecha o parte inferior:


#contenedor {
   position:relative; /* necesario */
   z-index:1; /* necesario para ordenar las cosas correctamente */
}
#contenedor:before {
   content:"";
   position:absolute; /* necesario */
   z-index:-1;  /* necesario para ordenar las cosas correctamente */
   bottom:10px; /* Colocando respecto a la parte inferior */
   right:10px;  /* Colocando respecto a la parte derecha  */
   width:500px; height:300px;
   background:url(image.jpg);
}

Emulando background-opacity
Desarrollando un poco las técnicas que hemos estado viendo antes, se puede aplicar opacity al background de uno de los dos pseudo-elementos :before o :after de modo que se hagan transparencias con el background del propio elemento.


#contenedor {
   position:relative;
   z-index:1;
}
#contenedor:before {
   content:"";
   position:absolute;
   z-index:-1;
   top:0; bottom:0; left:0; right:0;
   background:url(image.jpg);
   opacity:0.7;
}
Una vuelta de tuerca a todo esto es la de que el :before tuviera una transparencia de por ejemplo .75 y simplemente cambiando el z-index de -1 a 1, no solo hacemos que se vea el contenido de forma translúcida, si no que además no se permitiría la selección por ratón!. He oido por ahí "selection-disabled"?. Lástima que ya exista, pero seguro que algún uso se le puede dar...
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-o-user-select: none;
user-select: none;

No hay comentarios:

Publicar un comentario