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.
Creación de un píxel base
El primer paso, obviamente, será crear el pixel base en nuestro documento:
.pixel {
background: black;
width: 32px;
height: 32px;
}
<div class="pixel"></div>
Una vez lo tenemos, todo se basará en utilizar box-shadow
para crear nuevos píxels con desplazamiento.
Creación de siguientes píxels
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 (color dorado):
.pixel {
background: black;
width: 32px;
height: 32px;
box-shadow:
32px 0 0 red,
64px 0 0 gold;
}
<div class="pixel"></div>
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;
}
<div class="pixel"></div>
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()
.
Usando Javascript para reutilizar
A continuación puedes ver un ejemplo más elaborado, donde utilizamos Javascript para simplificar nuestro código HTML y CSS, y generar los fragmentos repetibles. Observa que el HTML/CSS sólo tiene los detalles genéricos, y el resto lo creamos desde Javascript:
body {
height: 350px;
background: #44a;
}
.avatar {
width: 256px;
margin: 2em auto;
height: 256px;
background: linear-gradient(#8A4BEC, #E91DCF);
overflow: hidden;
border: 10px solid #fff;
border-bottom-width: 50px;
box-shadow:
2px 2px 8px #0006,
4px 4px 25px #0008 inset;
transform: rotate(-5deg);
}
.pixel {
height: 17px;
width: 17px;
box-shadow: var(--shadow);
transform: rotate(-5deg) translate(-10px, 22px);
filter: drop-shadow(2px 2px 10px #0007);
}
<div class="avatar">
<div class="pixel"></div>
</div>
const COLORS = {
0: "transparent",
1: "#000",
2: "#fff",
3: "#ffcc80",
4: "#cc984f",
5: "#1a1a1a",
6: "#ebb267",
7: "#0d2061",
8: "#17ffff",
9: "#cc2554",
10: "#e65100"
}
const PIXEL_ART = [
0,0,0,0,2,2,2,2,2,2,2,2,0,0,0,0,
0,0,0,2,2,1,1,1,1,1,1,2,2,2,0,0,
0,0,2,2,1,1,1,1,1,1,1,1,1,2,0,0,
0,0,2,1,1,1,4,4,4,4,5,1,1,2,0,0,
0,0,2,1,1,5,3,3,3,3,6,6,2,2,0,0,
0,0,2,1,5,3,3,1,3,3,1,3,2,0,0,0,
0,0,2,1,5,3,3,1,3,3,1,3,2,0,0,0,
0,0,2,1,1,3,3,3,6,6,6,3,2,0,0,0,
0,0,2,1,1,4,3,3,3,3,3,3,2,0,0,0,
0,0,2,2,1,1,4,4,4,1,1,3,2,0,0,0,
0,0,0,2,2,1,1,1,4,4,1,4,2,0,0,0,
0,0,2,2,1,5,1,1,1,1,1,1,2,0,0,0,
0,0,2,1,5,1,1,1,1,1,1,1,2,0,0,0,
0,0,2,1,5,1,1,1,8,1,1,5,2,0,0,0,
0,0,2,5,1,1,1,9,7,7,1,5,2,0,0,0,
0,0,2,4,4,1,1,7,10,8,1,5,2,0,0,0
];
const boxShadow = PIXEL_ART.map((pixel, index) => {
const x = 16 * (index % 16);
const y = 16 * ~~(index / 16);
return `${x}px ${y}px ${COLORS[pixel]}`;
}).join(",\n");
const avatar = document.querySelector(".avatar");
avatar.style.setProperty("--shadow", boxShadow);
A grandes rasgos, hemos hecho lo siguiente:
- 1️⃣ La constante
COLORS
es la paleta de colores (cada color es un número). - 2️⃣ La constante
PIXEL_ART
es el lienzo y los colores que se usan. - 3️⃣ En las siguientes líneas, recorremos el array
PIXEL_ART
para crear los valores de la propiedadbox-shadow
de CSS, de forma automática.