Eduardo Cortez
1 October, 2025
Cada imagen que cargas crea una solicitud al servidor. Aunque HTTP/2/3 reduce esa sobrecarga, un menor número de solicitudes sigue significando:
Una técnica probada y comprobada para ello es el sprite CSS: combinar muchos iconos pequeños en una sola imagen y luego mostrar la pieza correcta con CSS. En este artículo vamos a:
Usaremos un sprite PNG de 120×120 (iconos.png) con 9 iconos (40×40 cada uno) en una cuadrícula 3×3:
Descargar el sprite (PNG)
Iconos: LinkedIn, Instagram, Google | GitHub, Figma, Facebook | Clubhouse, Discord, Dribbble.
Opción A: posición de fondo clásica
HTML
<i class="sicon sicon--linkedin"></i> <i class="sicon sicon--instagram"></i> <i class="sicon sicon--google"></i>
CSS
:root {
--icon-size: 40px;
--sprite-cols: 3;
--sprite-rows: 3;
--sprite-url: url(“/assets/iconos.png”);
}
.sicon {
display:inline-block;
width:var(--icon-size);
height:var(--icon-size);
background-image:var(--sprite-url);
background-repeat:no-repeat;
background-size: calc(var(--sprite-cols) * var(--icon-size))
calc(var(--sprite-rows) * var(--icon-size));
background-position:
calc(var(--col,0) * -1 * var(--icon-size))
calc(var(--row,0) * -1 * var(--icon-size));
}
.sicon--linkedin { --col:0; --row:0; }
.sicon--instagram { --col:1; --row:0; }
.sicon--google { --col:2; --row:0; }
Escalado: sobrescribe --icon-size.
.sicon-mask {
width: var(--icon-size);
height: var(--icon-size);
background-color: currentColor;
-webkit-mask-image: var(--sprite-url);
mask-image: var(--sprite-url);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: calc(3 * var(--icon-size)) calc(3 * var(--icon-size));
mask-size: calc(3 * var(--icon-size)) calc(3 * var(--icon-size));
-webkit-mask-position:
calc(var(--col,0) * -1 * var(--icon-size))
calc(var(--row,0) * -1 * var(--icon-size));
mask-position:
calc(var(--col,0) * -1 * var(--icon-size))
calc(var(--row,0) * -1 * var(--icon-size));
}
<i class="sicon-mask sicon--instagram" style="color:#E1306C"></i>
Una ventaja interesante de los sprites: los estados de desplazamiento no requieren solicitudes adicionales.
Coloque dos estados de icono (predeterminado + desplazamiento) apilados verticalmente en la misma altura de celda y, a continuación, cambie la posición del fondo al desplazarse.
Ejemplo: icono normal de LinkedIn arriba, estado de desplazamiento abajo en el sprite.
.sicon--linkedin {
--col:0;
--row:0; /* default */
}
.sicon--linkedin:hover {
--row:1; /* hover state right below */
}
De esta manera, solo se carga un archivo para ambos estados, lo que mantiene un alto rendimiento y una alineación perfecta al píxel.
No es necesario calcular las posiciones a mano. Aquí hay un elemento personalizado JS básico <sprite-icon> y una utilidad para los atributos del conjunto de datos.
(Anteriormente hemos cubierto el código completo con correcciones de accesibilidad, alternativas y protecciones de entrada; consulte el fragmento de código en el cuerpo del artículo).
Uso:
HTML
<sprite-icon src="/assets/iconos.png" cols="3" rows="3" col="1" row="0" size="24"></sprite-icon> <sprite-icon src="/assets/iconos.png" cols="3" rows="3" col="1" row="0" size="24" mode="mask" tint="#E1306C"></sprite-icon>
Accesibilidad
Iconos decorativos → aria-hidden="true
Iconos significativos → añadir role="img" + aria-label=«LinkedIn»
Nuestro componente JS gestiona esto automáticamente de forma correcta.
Reducir las solicitudes sigue siendo una ventaja fundamental para el rendimiento web. Los sprites CSS, aunque son un nombre antiguo, siguen siendo una herramienta sencilla y potente para los iconos:
Si trabajas con un conjunto fijo de iconos rasterizados (como logotipos de redes sociales), esta es una de las optimizaciones más rápidas que puedes realizar en 2025..