Sombras CSS en cajas

La propiedad box-shadow

Se denominan sombras sobre cajas a las sombras en CSS que se pueden crear en una etiqueta o elemento HTML. Para ello, se utiliza la propiedad box-shadow, que funciona de forma muy similar a la que vimos en las sombras de texto, sólo que con algunos añadidos interesantes.

En primer lugar, las sombras box-shadow están desactivadas sobre cualquier elemento, lo mismo que ocurriría si aplicamos el valor none a dicha propiedad. Veamos un resumen de valores que podemos indicar a esta propiedad de sombras:

Propiedad Valor Significado
box-shadow none Elimina (o simplemente no establece) sombra sobre un elemento.
box-shadow Crea una sombra color negro desplazándola ligeramente en horizontal y/o vertical.
box-shadow Idem a la anterior, pero desenfocando o difuminando la sombra.
box-shadow Idem a la anterior, pero además aplicando un factor de crecimiento a la sombra.
box-shadow Idem a la anterior, cambiando el color de la sombra.
box-shadow inset Idem a la anterior, pero estableciendo una sombra interna en lugar de externa.

La palabra clave inset se puede escribir en cualquier otro orden, pero se suele indicar al final. Veamos cada uno de estos parámetros, uno por uno, junto a sus peculiaridades.

Desplazamiento de la sombra

Los dos primeros parámetros, y , son los parámetros obligatorios mínimos para hacer funcionar la propiedad box-shadow, donde indicamos el desplazamiento que tendrá la sombra en el eje x (horizontal) y en el eje y (vertical).

Así pues, si queremos desplazar una sombra ligeramente a la derecha (eje x, primer parámetro) y hacia abajo (eje y, segundo parámetro), tendríamos que escribir, como mínimo, algo similar a lo siguiente:

.element {
box-shadow: 5px 5px;
}

En este caso, la sombra se crea de color currentColor (habitualmente black) y sin difuminar, como veremos en los siguientes apartados. Ten en cuenta que valores negativos invierten la dirección de la sombra. Si 5px 5px mueve la sombra 5 píxels a la derecha y hacia abajo, -5px -5px movería la sombra 5 píxels a la izquierda, y 5 píxels hacia arriba.

Desenfoque de la sombra

El tercer parámetro de la propiedad box-shadow indica la cantidad de desenfoque o difuminado que queremos utilizar en nuestra sombra. Por defecto, tiene un valor de 0, o lo que es lo mismo, la sombra será igual a la caja original, por lo que será completamente lisa, sin difuminar. Este valor puede irse ampliando y de esta forma conseguiremos una sombra más desenfocada:

.element {
box-shadow: 5px 5px 0; /* Sombra sin desenfoque */
box-shadow: 5px 5px 2px; /* Sombra con ligero desenfoque */
box-shadow: 5px 5px 10px; /* Sombra desenfocada */
box-shadow: 5px 5px 40px; /* Sombra con un desenfoque casi disipado */
}

Ten en cuenta que las sombras con box-shadow siempre serán rectangulares. Si quisieramos una sombra idéntica, por ejemplo, a una imagen con transparencia, donde se respeten los espacios transparentes, deberías ver la función drop-shadow() de la propiedad filter, que explicamos más adelante.

Factor de crecimiento

Un cuarto parámetro opcional permite indicar un factor de crecimiento para la sombra. Este valor no es obligatorio escribirlo, y muchas veces comprobarás que el cuarto parámetro de la propiedad box-shadow es el color, es decir, el siguiente apartado, omitiendo este parámetro. Esto es absolutamente normal, ya que este parámetro es opcional y se indica sólo cuando es necesario. En caso contrario, este parámetro valdrá 0 y será omitido.

El parámetro de factor de crecimiento es un parámetro donde podemos indicar una unidad que hará crecer la sombra en todos sus lados el tamaño indicado, de forma que crezca un poco más de lo que ocupa. Algo que puede ser realmente útil, por ejemplo, en el caso de que el desplazamiento sea 0 (la sombra está justo detrás del elemento) y queremos que se muestre ligeramente alrededor de la etiqueta a la que le aplicamos box-shadow. Veamos un ejemplo:

.element {
box-shadow: 0 0 10px 5px;
}

Esto hará que la sombra esté posicionada justo detrás del elemento, tenga un nivel de desenfoque de 10px y, además, la hagamos crecer unos 5px por cada lado.

Color de la sombra

Aunque en los ejemplos anteriores lo hemos omitido por el momento, lo habitual es que las sombras creadas con box-shadow incluyan siempre cuatro valores: desplazamiento de x, desplazamiento de y, nivel de desenfoque y color de la sombra. Luego, el factor de crecimiento y la palabra clave inset que veremos posteriormente, son opcionales y se usan sólo cuando son necesarias.

.element {
box-shadow: 15px 5px 10px #48529944;
}

Con el parámetro del color podemos cambiar el color de la sombra a nuestro antojo, no sólo utilizando palabras clave, valores hexadecimales y/o las funciones rgb() o hsl(), sino utilizando canales alfa para conseguir cierta transparencia, si así lo deseamos. En el ejemplo anterior utilizamos el color #485299 con una transparencia en hexadecimal de 44, teniendo en cuenta que los valores de canal alfa en hexadecimal van desde 00 (totalmente transparente) hasta ff (totalmente opaco).

Sombra interior

Nuestras sombras creadas con box-shadow permiten indicar la palabra clave inset, lo que hará que la sombra en lugar de colocarse por fuera de nuestro elemento y ser una sombra exterior (por defecto), pasará a ser una sombra interior y colocarse por dentro del elemento. Ten en cuenta que en este caso, los desplazamientos indicados se invierten, de modo que si teníamos una sombra por la zona inferior-derecha, tendríamos que invertir los valores para que la sombra interior también esté en la zona inferior-derecha:

.element {
/* Sombra exterior que se desplaza hacia la zona inferior-derecha */
box-shadow: 10px 10px 5px black;

/* Sombra interior que se desplaza hacia la zona inferior-derecha */
box-shadow: -10px -10px 5px black inset;
}

Observa que hemos invertido los valores de los desplazamientos de y .

Sombras de texto múltiples

Como hemos visto en otros casos como en propiedades como background-image o text-shadow, la propiedad box-shadow permite indicar valores múltiples separados por coma, permitiendo en este caso, crear sombras múltiples e independientes.

La sintaxis es muy sencilla y se suele escribir así para hacerlo más legible:

.element {
box-shadow:
5px 5px 10px black,
10px 10px 10px red,
20px 20px 10px blue,
10px 10px 10px rgb(0,0,0, 0.5) inset;
}

En este caso hemos creado múltiples sombras de diferentes colores y con diferentes desplazamientos, incluso una de ellas una sombra interior.

Pixel art con box-shadow

Existe una técnica muy curiosa con la que se puede hacer pixel art sólo con CSS (o incluso combinar con bucles Javascript y hacerlo más flexible). A grandes rasgos, se trata de crear un elemento de un tamaño muy específico (por ejemplo, 32 pixels) y crear sombras sin desenfoque con el desplazamiento adecuado que simulen los pixels.

De esta forma, en primer lugar creamos el pixel base:

<div class="pixel"></div>

<style>
.pixel {
background: black;
width: 32px;
height: 32px;
}
</style>

Una vez lo tenemos, todo se basa en utilizar box-shadow para crear nuevos píxels con desplazamiento. Aquí puedes ver como creamos una sombra roja (se creará del mismo tamaño que el píxel base) y la desplazamos exactamente 32px a la derecha, por lo que aparecerá justo al lado del píxel base. Lo mismo con el siguiente píxel (dorado):

.pixel {
background: black;
width: 32px;
height: 32px;

box-shadow:
32px 0 0 red,
64px 0 0 gold;
}

Para hacer el código más flexible y fácil de mantener, podemos hacer uso de variables CSS y organizar/reescribir un poco el código. Quizás puede ser más difícil de leer si no tienes cierta soltura con CSS, pero es mucho más flexible si necesitamos cambiar tamaños o similar:

.pixel {
--size: 32px;

background: black;
width: var(--size);
height: var(--size);

box-shadow:
calc(1 * var(--size)) 0 0 gold,
calc(2 * var(--size)) 0 0 blue,
0 calc(1 * var(--size)) 0 red,
calc(1 * var(--size)) calc(1 * var(--size)) 0 hotpink;
}

Ahora podríamos cambiar el valor de la CSS custom property --size y el resto del código se adaptaría automáticamente, gracias a que hemos utilizado cálculos con la función calc() y variables css con la función var().

DigitalOcean
Tabla de contenidos