Sombras en CSS

Una de las carencias del estándar CSS 2.1 más demandadas por los diseñadores es la posibilidad de mostrar sombras tipo «drop shadow» sobre cualquier elemento de la página. Por este motivo, la futura versión CSS 3 incluirá una propiedad llamada box-shadow para crear este tipo de sombras.

A continuación se muestra la regla CSS 3 necesaria para crear una sombra gris muy difuminada y que se visualice en la esquina inferior derecha de un elemento:

.elemento {
  box-shadow: 2px 2px 5px #999;
}

Desafortunadamente, esta propiedad sólo está disponible en los navegadores que más se preocupan por los estándares. El navegador Safari 3 incluye la propiedad con el nombre -webkit-box-shadow y Firefox 3.1 la incluye con el nombre -moz-box-shadow.

La sintaxis completa de la propiedad box-shadow es muy compleja y se define en el borrador de trabajo del módulo de fondos y bordes de CSS3. A continuación se muestra su sintaxis simplificada habitual:

box-shadow: <medida> <medida> <medida>? <medida>? <color>
  • La primera medida es obligatoria e indica el desplazamiento horizontal de la sombra. Si el valor es positivo, la sombra se desplaza hacia la derecha y si es negativo, se desplaza hacia la izquierda.
  • La segunda medida también es obligatoria e indica el desplazamiento vertical de la sombra. Si el valor es positivo, la sombra se desplaza hacia abajo y si es negativo, se desplaza hacia arriba.
  • La tercera medida es opcional e indica el radio utilizado para difuminar la sombra. Cuanto más grande sea su valor, más borrosa aparece la sombra. Si se utiliza el valor 0, la sombra se muestra como un color sólido.
  • La cuarta medida también es opcional e indica el radio con el que se expande la sombra. Si se establece un valor positivo, la sombra se expande en todas direcciones. Si se utiliza un valor negativo, la sombra se comprime.
  • El color indicado es directamente el color de la sombra que se muestra.

La siguiente regla CSS muestra una sombra en los navegadores Firefox y Safari:

.elemento {
  -webkit-box-shadow: 2px 2px 5px #999;
  -moz-box-shadow: 2px 2px 5px #999;
}

Por su parte, el navegador Internet Explorer dispone de su propio mecanismo para crear sombras. La solución se basa en el uso de los filtros, un mecanismo que no forma parte del estándar de CSS y que permiten aplicar operaciones complejas a los elementos de la página. Entre los filtros de Internet Explorer, se encuentra el filtro shadow, que permite mostrar una sombra en un elemento de la página.

Las opciones del filtro shadow son mucho más limitadas que las de la propiedad box-shadow. Su sintaxis es la habitual de los filtros de Internet Explorer y las opciones son:

  • color, establecido mediante el formato hexadecimal (ejemplo: #CC0000).
  • direction, dirección hacia la que se desplaza la sombra. Su valor se indica en grados y sólo se permiten los valores 0, 45, 90, 135, 180, 225, 270 y 315.
  • strength, distancia en píxeles hasta la que se extiende la sombra.

A continuación se modifica la regla CSS anterior para incluir el filtro de Internet Explorer que muestra una sombra similar:

.elemento {
  -webkit-box-shadow: 2px 2px 5px #999;
  -moz-box-shadow: 2px 2px 5px #999;
  filter: shadow(color=#999999, direction=135, strength=2);
}

Lamentablemente, hasta que todos los navegadores más utilizados no incluyan la propiedad box-shadow, la única forma de mostrar una sombra sobre un elemento de la página consiste en utilizar imágenes que simulan una sombra.

A continuación se detallan los pasos necesarios para mostrar una sombra sencilla sobre una imagen:

  1. Se crea una imagen del mismo tamaño que la imagen original y cuyo aspecto sea el de la sombra que se quiere mostrar.
  2. Se añade un espacio de relleno a la imagen original en la posición en la que se quiere mostrar la sombra. Si por ejemplo se quiere mostrar una sombra en la esquina inferior derecha, se añade padding-right y padding-bottom.
  3. Utilizando la propiedad background, se añade la imagen de la sombra como imagen de fondo de la imagen original. La imagen de fondo se coloca en la posición en la que se quiere mostrar la sombra. En el caso de la sombra inferior derecha, la posición de la imagen de fondo es bottom right.
Aplicando una sombra a una imagen
Aplicando una sombra a una imagen

El código CSS necesario para conseguir este efecto se muestra a continuación:

img {
  background: url("imagenes/sombra.png") no-repeat bottom right;
  padding-right:  10px;
  padding-bottom: 10px;
}

El principal inconveniente de esta técnica sencilla es que se deben crear tantas imágenes de sombra como tamaños diferentes de imágenes haya en el sitio web. La solución a este problema consiste en crear una imagen de sombra muy grande y aplicarla a todas las imágenes. Esta nueva sombra debe tener un tamaño al menos tan grande como la imagen más grande que se vaya a utilizar.

El problema de utilizar una imagen de sombra muy grande es que los bordes de la sombra no quedan tan bien como cuando se utiliza una imagen de sombra del mismo tamaño que la imagen original:

Las imágenes de sombra muy grande producen bordes más feos
Las imágenes de sombra muy grande producen bordes más feos

La solución completa para crear sombras de cualquier tamaño y con bordes correctos implica el uso de más imágenes. Los siguientes recursos muestran cómo crear ese tipo de sombras:

Si se quiere mostrar una sombra sobre elementos que no sea imágenes, la solución consiste en encerrar los contenidos con dos elementos <div> y aplicar la imagen de sombra sobre el primero de ellos:

#sombra {
  background: url("imagenes/sombra_grande.png") no-repeat 100% 100%;
  padding-right: 15px;
  padding-bottom: 15px;
  width: 200px;
}
 
#sombra div {
  background: #FFF;
  width: 200px;
}
 
<div id="sombra">
  <div>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut diam metus, venenatis ullamcorper, 
consequat sit amet, volutpat at, nulla. Nulla sollicitudin metus.</div>
</div>

Las soluciones basadas en imágenes tienen la ventaja de que funcionan correctamente en cualquier navegador. Sin embargo, complican innecesariamente el código HTML de la página y tienen limitaciones como la de tener que crear una nueva imagen cada vez que se quiere cambiar el color de la sombra