¿Alguna vez has notado cómo sitios como LinkedIn o YouTube muestran una estructura gris antes de cargar el contenido real? Esta técnica se conoce como Skeleton Screen y es fundamental para mejorar la percepción de velocidad y evitar saltos de diseño (CLS).
En este artículo, vamos a crear un componente de carga reutilizable utilizando CSS puro, aprovechando la potencia del pseudo-selector :empty y las Custom Properties.
¿Qué es el selector :empty?
El selector :empty es una herramienta muy útil que permite aplicar estilos a un elemento solo cuando no tiene hijos (ni elementos HTML, ni texto, ni siquiera espacios en blanco).
Esto lo hace perfecto para estados de carga:
- Si el contenedor está vacío -> Muestra el Skeleton.
- En cuanto inyectas contenido (vía JS/API) -> El Skeleton desaparece automáticamente y se muestran los estilos normales.
Dibujando con CSS Gradients
Para evitar ensuciar el HTML con divs vacíos para simular las barras y círculos, usaremos background-image con múltiples gradientes.
He diseñado este ejemplo para que sea altamente configurable mediante Variables CSS:
--color: El color base del esqueleto.--height-rectangle: Altura del bloque principal (imagen destacada).--height-line: Altura de las líneas de texto/avatar.
La magia ocurre combinando 4 capas de fondo:
- Brillo: Un gradiente lineal con transparencia para simular profundidad o brillo.
- Rectángulo principal: Simula una imagen o banner.
- Círculo: Un
radial-gradientpara simular un avatar. - Línea de texto: Un bloque rectangular junto al círculo.
Aquí tienes el código completo:
.card__content:empty {
--color: rgb(199, 199, 199);
--width: 100%;
--width-line: 250px;
--height-rectangle: 150px;
--height-line: 24px;
--gutter: 10px;
--computed-circle-rad: calc(var(--height-line) * 0.5);
--computed-height: calc(var(--height-rectangle) + var(--gutter) + var(--height-line) + calc(1.5 * var(--gutter))
);
height: var(--computed-height);
background-image:
linear-gradient(0.9turn, #fff, transparent),
linear-gradient(var(--color), var(--color)),
radial-gradient(var(--height-line) circle at var(--computed-circle-rad) var(--computed-circle-rad), var(--color) 50%, transparent 50%),
linear-gradient(var(--color), var(--color));
background-size:
var(--width) var(--computed-height),
var(--width) var(--height-rectangle),
var(--height-line) var(--height-line),
var(--width-line) var(--height-line);
background-position:
var(--width) 0,
0 0,
0px calc(var(--height-rectangle) + var(--gutter)),
calc(var(--height-line) + var(--gutter)) calc(var(--height-rectangle) + var(--gutter));
background-repeat: no-repeat;
}
Ver el Pen Skeleton Loading con CSS: Dominando el selector :empty por Iván Albizu (@ivan_albizu) en CodePen.
En este repositorio puede verse el código del placehoder con CSS para selector :empty