Hola.
Hoy vamos a meternos con un pequeño experimento de CSS que, aunque visualmente parece bastante más complejo de lo que realmente es, demuestra muy bien hasta dónde podemos llegar combinando transformaciones 2D, pseudo-elementos y sombras.
Vamos a crear desde cero un icono con apariencia 3D utilizando únicamente HTML y CSS.
La idea es construir una especie de tarjeta o bloque tridimensional a partir de un elemento plano y añadirle profundidad mediante sus caras laterales.
Como podéis ver en el resultado, podemos utilizar Font Awesome para colocar el icono en el interior, aunque realmente esto es lo de menos. Podéis sustituirlo por un SVG, una imagen, texto o cualquier otro elemento que queráis.
Lo interesante del ejemplo está en cómo conseguimos crear la sensación de profundidad utilizando exclusivamente CSS.
La idea detrás del efecto 3D
Antes de entrar en el código, conviene entender qué estamos haciendo.
CSS no está creando realmente un objeto 3D. Lo que hacemos es engañar visualmente al navegador y al usuario combinando varias transformaciones:
- rotate() para inclinar el elemento.
- skewX() y skewY() para deformarlo y simular perspectiva.
- ::before para crear una de las caras laterales.
- ::after para crear otra cara.
- box-shadow para reforzar la sensación de profundidad.
- transition para animar el conjunto cuando pasamos el ratón por encima.
Por tanto, realmente estamos construyendo varias piezas que, juntas, producen la ilusión de un objeto tridimensional.
El contenedor principal
Comenzamos preparando un pequeño reset y centrando nuestro elemento en la pantalla:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #cdcccc;
display: flex;
justify-content: center;
align-items: center;
min-height: 90vh;
font-family: Arial, Helvetica, sans-serif;
}
El body utiliza Flexbox únicamente para centrar nuestro elemento horizontal y verticalmente.
Ahora vamos con el elemento que realmente formará nuestro bloque:
.icons {
position: relative;
width: 200px;
height: 400px;
transform: rotate(-37.5deg) skewX(10deg);
box-shadow: -35px 35px 50px rgba(0, 0, 0, 1);
transition: 0.5s;
}
Aquí empiezan a ocurrir cosas interesantes.
La propiedad:
transform: rotate(-37.5deg) skewX(10deg);
aplica dos transformaciones al mismo elemento.
Primero lo giramos y después aplicamos una deformación horizontal mediante skewX(). Esta combinación es la que proporciona buena parte de la apariencia inclinada del objeto.
Creando el efecto al pasar el ratón
Ya que estamos, podemos hacer que el objeto reaccione cuando el usuario pase el ratón sobre él:
.icons:hover {
background: #285e97;
transform: rotate(-37.5deg) skewX(10deg)
translate(20px, -20px);
box-shadow: -50px 50px 100px rgba(0, 0, 0, 1);
color: #2196f3;
}
Fijaos en que no estamos cambiando solamente el color.
También utilizamos translate() para desplazar ligeramente el elemento y modificamos la sombra para que parezca que el bloque se ha elevado.
Es un pequeño detalle, pero es precisamente este tipo de combinación entre movimiento, sombras y transformación lo que hace que el efecto resulte mucho más convincente.
Construyendo la primera cara lateral
Ahora viene una de las partes más interesantes del ejemplo: los pseudo-elementos.
Con ::before podemos crear una pieza adicional sin tener que añadir otro elemento al HTML:
.icons::before {
content: '';
width: 25px;
height: 100%;
top: 0;
left: 0;
background: #9b9797;
position: absolute;
transform: skewY(-45deg) translate(-24px, -12px);
box-shadow: inset -10px 0 20px rgba(0, 0, 0, 0.2);
}
Esta pequeña pieza representa una de las caras laterales de nuestro bloque.
Lo importante aquí es:
transform: skewY(-45deg) translate(-24px, -12px);
Con skewY() deformamos verticalmente el elemento y con translate() lo desplazamos hasta colocarlo en el lugar adecuado.
El resultado es una cara lateral que, visualmente, parece formar parte del objeto principal.
Creando la segunda cara
Hacemos exactamente lo mismo con ::after, pero esta vez para crear la cara inferior:
.icons::after {
content: '';
width: 100%;
height: 25px;
bottom: 0;
left: 0;
background: #ccc;
transform: skewX(-45deg) translate(12px, 24px);
box-shadow: inset -10px 0 20px rgba(0, 0, 0, 0.2);
}
Tenemos ahora tres piezas visuales:
- La superficie principal.
- La cara lateral creada mediante
::before. - La cara inferior creada mediante
::after.
Y las tres juntas generan la ilusión de un bloque tridimensional.
Colocando el icono
Una vez construido el bloque, solamente nos falta colocar el icono.
En este ejemplo utilizamos Font Awesome, pero podéis utilizar cualquier recurso que queráis:
.fb {
color: black;
position: absolute;
font-size: 64px;
top: 32%;
left: 38%;
transition: 0.5s;
}
Y podemos cambiar su aspecto al pasar el ratón:
.fb:hover {
color: white;
cursor: pointer;
}
No es necesario volver a declarar position, top o left dentro del :hover, ya que esas propiedades no cambian.
Es una pequeña simplificación respecto al código original y hace que la regla sea más limpia.
El HTML
Ahora solamente necesitamos nuestro contenedor:
<div class="icons">
<i class="fa fa-facebook fb" aria-hidden="true"></i>
</div>
Si utilizáis una versión moderna de Font Awesome, recordad que las clases de los iconos pueden ser diferentes dependiendo de la versión instalada.
Por ejemplo, con las versiones actuales es habitual encontrarnos con una sintaxis basada en fa-brands, mientras que el ejemplo original utiliza la nomenclatura antigua de Font Awesome.
¿Qué está haciendo realmente CSS?
Una vez visto todo el código, podemos resumir el efecto de una forma bastante sencilla:
Elemento principal
│
├── rotate()
│
├── skewX()
│
├── box-shadow
│
├── ::before → cara lateral
│
└── ::after → cara inferior
No estamos utilizando un motor 3D ni un modelo tridimensional real.
Estamos utilizando geometría 2D y composición visual para conseguir un resultado que nuestro cerebro interpreta como profundidad.
Personalizando el efecto
Una de las ventajas de hacerlo directamente con CSS es que podemos modificar prácticamente cualquier parte del efecto.
Podemos cambiar, por ejemplo:
- El tamaño del bloque.
- El ángulo de rotación.
- La inclinación mediante
skew(). - El color de las caras.
- La intensidad de la sombra.
- El tamaño del icono.
- La distancia del desplazamiento al hacer
:hover. - La duración de la transición.
Por ejemplo, si queremos que el bloque tenga un aspecto más discreto, podemos reducir considerablemente la sombra:
box-shadow: -20px 20px 35px rgba(0, 0, 0, 0.35);
O podemos modificar la transformación para obtener otra perspectiva:
transform: rotate(-30deg) skewX(8deg);
¿Y podemos utilizar otros iconos?
Por supuesto.
El CSS no sabe ni le importa qué icono estamos utilizando. Para él simplemente existe un elemento dentro de .icons.
Podemos utilizar un icono de Facebook, Instagram, GitHub, LinkedIn, X o incluso sustituirlo por nuestro propio SVG.
Por ejemplo:
<div class="icons">
<i class="fa fa-github fb" aria-hidden="true"></i>
</div>
Y tendríamos prácticamente el mismo efecto visual con otro icono.
Resultado final
Y este es el resultado del experimento:

Como podéis comprobar, con unas cuantas propiedades CSS podemos conseguir efectos bastante llamativos sin necesidad de recurrir a imágenes previamente renderizadas.
Conclusión
Este ejemplo es especialmente interesante porque demuestra que muchas veces no necesitamos JavaScript ni una herramienta externa para conseguir una interfaz con cierto nivel de profundidad.
Con transform, pseudo-elementos, sombras y un poco de imaginación podemos construir componentes visuales bastante elaborados partiendo prácticamente de un único elemento HTML.
Y aquí está precisamente lo divertido de CSS: empezar con un simple <div> y terminar haciendo que parezca que tienes un pequeño objeto flotando delante de ti. 😎
Un saludo y nos vemos en el próximo experimento.
Visitas: 500
Automation & Data Specialist | Web Development | Data Processing & Integration
