Fondos: La propiedad {background} de CSS-3

En CSS-3 se desglosa la especificación oficial del W3C en varios documentos o módulos. El relacionado con fondos es CSS Backgrounds and Borders Module Level 3. En mi glosario XHTML 1.0 + CSS 2.1 ya estudié la parte relacionada con fondos en CSS21 {background}. En estos temas veré que diferencias aporta CSS-3 resumiendo que propiedades se mantienen igual y exponiendo las nuevas.

Fases de una especificación W3C

En la página CSS current work puede ver la situación actual de los distintos módulos de trabajo del W3C en relación con CSS. Las especificaciones del W3C pasan por los siguientes estados:

  • WD: Working Draft, fase de borrador. Es un documento del W3C publicado para revisión por la comunidad.
  • LC: Last Call, última llamada. Es un nivel posterior de maduración del borrador. Se proponen fechas límite para revisiones, identifica dependencias conocidas y solicita revisión de los diferentes grupos de trabajo así como revisión pública.
  • CR: Candidate Recommendation, candidato a recomendación. Es un documento que el W3C cree que ha sido profundamente revisado y satisface los requisitos exigidos por los grupos de trabajo. W3C publica este documento para recoger experiencias de las implementaciones finales.
  • PR: Proposed Recommendation, recomendación propuesta. Es un informe técnico sobre el grado de madurez alcanzado tras revisiones anteriores y que se expone para la aprobación final del W3C.
  • REC: Recommendation, recomendación. Un documento REC es una especificación o conjunto de guias que tras una extensa elaboración consensuada, ha recibido la aprobación de los miembros y dirección del W3C. En definitiva, una recomendación del W3C es equivalente a un estándar de otras organizaciones.

El módulo de fondos y bordes CSS Backgrounds and Borders Module Level 3 se encuentra en fase CR Candidate Recommendation en la fecha en que escribo estos temas: 30 de Septiembre de 2011. También en esta fecha he probado los contenidos en los navegadores Firefox 7.0.1, Opera 11.51, Chrome 14.0 y Safari 5.0. Cuando mencione estos navegadores en la exposición de estos temas me estaré refiriendo a estas versiones. Tener en cuenta que lo que se expone como que no funciona para una determinada versión es posible que si lo haga en versiones más recientes cuando esté leyendo estos temas. En cuanto a Explorer he decidido ni siquiera molestarme en probarlo por ahora, aunque es posible que muchas cosas funcionen en IE9. En IE8 y anteriores nada de CSS-3 funcionará.

Imagen de fondo CSS-3 {background-image}

Con CSS21 {background-image} podíamos declarar una única imagen. Ahora en CSS-3 podemos declarar más de una imagen para el fondo, separando por comas las expresiones url(ruta). En este ejemplo incorporamos las imágenes llave izquierda y llave derecha para encerrar un texto en un elemento <span>. Observar que separamos los valores de cada propiedad con comas para cada fondo: ...url(), url(); ...left, right; .... El código es el siguiente:

<span style="background-image: url(ejemplos/llave-izq.gif), 
url(ejemplos/llave-der.gif);
background-repeat: no-repeat, no-repeat;
background-position: left, right;
padding: 1.2em; ">Pellentesque...</span>

Es lo mismo que en CSS-2.1 pero con más de una imagen, ponemos no-repeat para evitar repeticiones y posicionamos cada imagen en un extremo.

Ejemplo:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.

Valores space y round para repetición de fondo CSS-3 {background-repeat}

Con CSS21 {background-repeat} declarábamos cómo se repetía la imagen de fondo, permitiéndose un unico valor entre repeat, repeat-x repeat-y y no-repeat. Con CSS-3 se agregan dos nuevos valores space y round para declarar la repetición horizontal y vertical. Cuando se especifica un sólo valor se entenderá que el segundo es el mismo. Por ejemplo, poner repeat es lo mismo que poner repeat repeat y lo mismo para las otras a excepción de repeat-x que equivale a repeat no-repeat y repeat-y que es lo mismo que no-repeat repeat. Sólo Opera, Safari y Chrome permiten este valor múltiple. Sólo Opera trabaja con space y round.

En este primer ejemplo usamos el valor repeat que equivale a repeat repeat repitiendo tanto en horizontal como en vertical. Es el valor por defecto, repitiéndose la imagen de 32x32 píxeles bola en todo el fondo:

<div style="background-image: url(ejemplos/bola.gif);
background-repeat: repeat;">Pellentesque</div>

Ejemplo:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.

El valor repeat no-repeat establece que repite en horizontal y no repite en vertical:

<div style="background-image: url(ejemplos/bola.gif);
background-repeat: repeat no-repeat;">Pellentesque</div>

Ejemplo:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.

Lo anterior repeat no-repeat es lo mismo que poner repeat-x

<div style="background-image: url(ejemplos/bola.gif);
background-repeat: repeat-x;">Pellentesque</div>

Ejemplo:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.

Con el valor space (equivale a space space) deberá espaciar las imágenes para no cortar ninguna, tanto en horizontal como en vertical. Pero sólo Opera ejecuta este valor, aunque únicamente en vertical. Firefox ignora el valor y lo trata como repeat mientras que Safari y Chrome lo tratan como no-repeat. Si cambia el tamaño de la ventana verá que Opera pone tantos círculos en vertical como quepan completos, espaciando entre imágenes para que la primera y la última en vertical se ubiquen en los extremos superior e inferior.

<div style="background-image: url(ejemplos/bola.gif);
background-repeat: space;">Pellentesque</div>

Ejemplo:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.

Con el valor round (equivale a round round) rellenará todo el espacio sin cortar las imágenes, escalando imagenes al tamaño libre si fuera necesario. Esto quiere decir que si no hubiera espacio suficiente para la última o ese espacio es mayor que el que se necesita, entonces escalará todas las imagenes para que quepan. Al igual que el caso anterior, sólo funciona en Opera en vertical:

<div style="background-image: url(ejemplos/bola.gif);
background-repeat: round;">Pellentesque</div>

Ejemplo:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.

Valor local para desplazamiento de fondo CSS-3 {background-attachment}

Con CSS21 {background-attachment} controlábamos el desplazamiento de la imagen cuando hacemos scroll en la ventana con los valores fixed o scroll. Con CSS-3 tenemos el nuevo valor local.

Con el valor fixed la imagen permanece fija en el fondo al desplazar la página. Observe como es recortada por la izquierda (al comparar el ancho con la de los siguientes ejemplos). Esto es debido a que la imagen se fija a la caja de la página, en este caso al borde vertical izquierdo de la página y por tanto no se muestra lo que hay entre ese borde y el borde izquierdo del contenedor:

<div style="line-height: 3; padding-left: 6em;
background-image: url(ejemplos/80x56.jpg);
background-repeat: repeat-y; 
background-attachment: fixed;">...</div>

Ejemplo:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.

Ejemplo con valor scroll, el valor por defecto, el fondo se desplaza conjuntamente con toda la página. Ahora la imagen se fija al propio contenedor y no a la caja de la página como antes:

<div style="line-height: 3; padding-left: 6em;
background-image: url(ejemplos/80x56.jpg);
background-repeat: repeat-y; 
background-attachment: scroll;">...</div>

Ejemplo:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.

Con el valor local el desplazamiento se hace respecto a la barra del contenedor si la tuviera, como en este ejemplo con la propiedad {overflow: auto} que recorta lo que sobresale y pone una barra vertical de desplazamiento. En este caso al mover esta barra deberá moverse también el fondo con el contenido. Esto ha funcionado en Opera, Safari y Chrome. Firefox lo ignoran y lo trata como scroll, el valor por defecto.

<div style="height: 6em; overflow: auto; padding-left: 6em;
background-image: url(ejemplos/80x56.jpg);
background-repeat: repeat-y; 
background-attachment: local;">...</div>

Ejemplo:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus

Recorte de fondo CSS-3 {background-clip}

Esta nueva propiedad nos permite situar el fondo recortándolo o mejor dicho, ajustándolo según el borde de la caja del elemento con el valor border-box, de su relleno con padding-box o de su contenido con content-box. Con esta propiedad queda determinada el área de posicionamiento del fondo, es decir, el área donde será dibujado ese fondo. El valor por defecto es border-box, por lo que el fondo se dibuja por defecto en todo el elemento rellenando hasta el borde.

En estos ejemplos tenemos un contenedor <div> donde diferenciamos 4 zonas:

  1. Una franja azul con un grosor de 1em que formamos con margin: 1em; outline: blue solid 1em;. Digamos que esto es el "exterior" del elemento, pues la propiedad {outline} es para dar un contorno al elemento, parecida a {border} pero ubicada en el exterior.
  2. Una franja de color rojo con transparencia que formamos con border: rgba(255,0,0,0.25) solid 1em;. Es el propio borde del elemento.
  3. Una franja de color blanco que es el relleno con padding: 1em. El relleno es lo que separa el borde del contenido interior.
  4. El contenido interior con el texto y con ese fondo background-color: aqua de color azul agua.

En este primer ejemplo recortamos el fondo al contenido con content-box. El color azul agua se ajusta sólo al contenido de texto. Safari no ejecuta esto y lo aplica como el ejemplo border-box.

<div style="margin: 2em; outline: blue solid 1em;
padding: 1em; border: rgba(255,0,0,0.25)  solid 1em;
background-color: aqua;
background-clip: content-box;">...</div>

Ejemplo:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.

Ahora recortamos el fondo al contenido con padding-box. El color azul agua se ajusta ocupando el relleno:

<div style="margin: 2em; outline: blue solid 1em;
padding: 1em; border: rgba(255,0,0,0.25)  solid 1em;
background-color: aqua;
background-clip: padding-box;">...</div>

Ejemplo:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.

Con el valor border-box el color agua también rellena el borde. Como éste es de color rojo transparente y se dibuja encima del fondo, la transparencia roja deja entrever el color agua y produce un color diferente.

<div style="margin: 2em; outline: blue solid 1em;
padding: 1em; border: rgba(255,0,0,0.25)  solid 1em;
background-color: aqua;
background-clip: border-box;">...</div>

Ejemplo:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.

También podemos ver el efecto usando un fondo de imagen con los tres valores content-box, padding-box y border-box en ese orden. El reborde azul también es el contorno pero de 1px en este caso. Safari no aplica content-box y lo trata como border-box.

Ejemplo:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.

El punto de inicio del fondo CSS-3 {background-origin}

Esta propiedad especifica donde empieza a dibujarse el área de posicionamiento del fondo, área que se determina con la propiedad {background-clip}. En definitiva, determina el lugar donde comienza a dibujar el fondo. Con content-box comienza a dibujar en el borde superior izquierdo del contenido. Con padding-box comienza en el borde superior izquierdo del relleno. Con border-box lo hará en la esquina superior izquierda del propio borde. El valor por defecto es padding-box. Usamos la imagen

bola2

con una esquina en rojo para observar ese efecto. El código es igual sólo cambiando el valor resaltado para los tres casos content-box, padding-box y border-box en ese orden. No repetimos la imagen para ver con detalle sólo la primera que se dibuja y donde está el punto de inicio con la esquina roja de la imagen.

<div style="margin: 1px; outline: blue solid 1px;
width: 10em; float: left;
padding: 0.7em; border: rgba(255,0,0,0.25)  solid 0.7em;
background-origin: content-box;
background-repeat: no-repeat;
background-image: url(ejemplos/bola2.gif);">...</div>

Ejemplo:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.

Tamaño del fondo CSS-3 {background-size}

Esta propiedad establece el tamaño del fondo. Con el valor contain se escalará la imagen conservando su proporción ancho-alto para que ocupe toda el área de posicionamiento disponible, la cual queda determinada por las propiedades {background-clip} y {background-origin}. Si estas no se especifican toman los valores border-box y padding-box, por lo que el área de posicionamiento del fondo será todo el elemento incluso el borde aunque una imagen deberá quedar posicionada en la esquina superior izquierda del relleno.

Los valores posibles son contain, cover o dos valores de dimensiones de longitud, porcentajes o auto para el ancho y alto. Los porcentajes son relativos a las dimensiones del contenedor. Si se da un único valor de dimensión, porcentaje o auto se aplicará al ancho y alto al mismo tiempo.

En este ejemplo usamos la misma imagen del último ejemplo. En el primer caso con el valor contain por lo que la imagen se escalará en horizontal y vertical hasta que alguna de las dos toque un borde, rellenando así todo el área de posicionamiento. En este caso lo hace la vertical. Al final la imagen tiene que quedar completamente dentro del área de posicionamiento. El código es igual para los tres ejemplos cambiando sólo lo resaltado en amarillo:

<div style="margin: 1px; outline: blue solid 1px; width: 10em;
padding: 0.7em; border: rgba(255,0,0,0.25)  solid 0.7em;
background-size: contain;
background-repeat: no-repeat;
background-image: url(ejemplos/bola2.gif);">...</div>

Ejemplo:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.

Ahora con el valor cover el escalado se hace para que la imagen cubra todo el área de posicionamiento. Por lo tanto escala horizontalmente hasta llegar al borde derecho, aunque el escalado vertical continúe sobre el borde inferior superando el área de posicionamiento. Recordar que en estos ejemplos el área de posicionamiento es todo el elemento, pues {background-clip} es border-box por defecto, aunque la imagen se empieza a dibujar después del borde, es decir, en la esquina superior izquierda del área de relleno tiene que estar posicionada una imagen, pues {background-origin} es padding-box por defecto.

Ejemplo:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.

Además podemos dar una pareja de valores para el tamaño del ancho y alto de la imagen. En este ejemplo ponemos 16px auto lo que supone reducir a la mitad el ancho original de 32px y el alto será ajustado automáticamente para conservar la proporción original.

Ejemplo:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.

Fondo resumido CSS-3 {background}

Como otras propiedades CSS, podemos especificar todas las sub-propiedades de una sóla vez con la propiedad resumida {background}. Es lo que se denomina shorthand que se traduce como taquigrafía, taquigráfica aunque prefiero usar en este contexto el término resumida. La sintaxis es ahora nueva para CSS-3 y podemos expresarlo así:

  • Uno o más grupos de estos separados por comas cada grupo, cada uno para un fondo de imagen:
    • Una imagen según background-image
    • Y/O una posición según background-position opcionalmente seguido de "/" y un tamaño según background-size
    • Y/O una repetición según background-repeat
    • Y/O un desplazamiento según background-atachment
    • Y/O uno o dos valores border-box, border-padding, border-content. Con uno se adjudican a background-origin y background-clip. Con dos se adjudican a estos en ese orden.
  • Con el último grupo se puede agregar opcionalmente un valor de background-color.

Esta forma de agrupar sub-propiedades puede ahorrarnos espacio de código, pero son más díficiles de mantener. Este ejemplo dispone de todas ellas sin resumir y luego en un siguiente ejemplo las resumiremos:

<div style="width: 20em; padding: 1em; border: lime solid 1em;
background-color: yellow;
background-image: url(ejemplos/bola.gif);
background-repeat: repeat-y;
background-attachment: fixed;
background-position: 10%;
background-size: 2em 1em;
background-origin: border-box;
background-clip: content-box;">...</div>

Se trata de un contenedor donde se ajusta el fondo al contenido, con un color amarillo y una imagen (la bola azul de un ejemplo anterior) repetida verticalmente a un 10% desde la izquierda, con un tamaño de un ancho 2em y alto 1em, perdiendo la proporción, ajustada la repetición al contenido:

Ejemplo:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.

En cambio si ponemos todos los valores juntos tenemos lo siguiente:

<div style="width: 20em; padding: 1em; border: lime solid 1em;
background: yellow url(ejemplos/bola.gif) repeat-y fixed 
10% / 2em 1em border-box content-box;">...</div>

Con el mismo resultado, aunque sólo para Opera, pues los otros navegadores no lo interpretan como el resultado anterior. Firefox, Safari y Chrome no sacan ningún fondo, ni color, ni imagen:

Ejemplo:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.

Evidentemente las propiedades resumidas (shorthand) se basan en los valores y ocupan menos texto, pero resultan más díficiles de manejar a no ser que sepamos a que se corresponde cada valor. De no ser así tendríamos que consultar la documentación para saber como es la sintaxis y deducir las parejas propiedad-valor. Aparte de que, como en este caso, los navegadores pueden interpretar esa sintaxis resumida de diversas formas no siempre coincidentes con la especificación oficial.