Filters y backdrop-filter

Domina el sistema de filtros CSS: blur, brightness, contrast, saturate, drop-shadow y más. Aprende backdrop-filter para crear efectos glassmorphism y UI con profundidad.

La propiedad filter aplica efectos gráficos directamente sobre un elemento: desenfoque, brillo, contraste, sombras que respetan la forma real del elemento… Efectos que antes requerían imágenes editadas o librerías externas, ahora son CSS puro.


filter: las funciones disponibles

blur()

Desenfoca el elemento. Acepta valores en px o rem:

.card:hover img {
  filter: blur(4px);
  transition: filter 0.3s ease;
}

El blur afecta a todo el elemento incluyendo sus bordes. Si quieres que no se note el recorte en los bordes, añade overflow: hidden al contenedor.

brightness()

1 = original. Menos de 1 oscurece, más de 1 aclara:

.btn:hover {
  filter: brightness(1.15); /* 15% más brillante */
}
.desactivado {
  filter: brightness(0.5); /* oscurecido al 50% */
}

contrast()

Igual que brightness: 1 = original, mayor = más contraste, menor = más plano:

.imagen-artistica {
  filter: contrast(1.4) brightness(1.1);
}

saturate()

Controla la intensidad del color. 0 = escala de grises, 1 = original, mayor = más saturado:

/* La imagen se desatura y al hacer hover recupera el color */
.galeria img {
  filter: saturate(0.2);
  transition: filter 0.4s ease;
}
.galeria img:hover {
  filter: saturate(1);
}

grayscale()

Convierte a escala de grises. 0 = sin efecto, 1 = gris total:

.logo-footer {
  filter: grayscale(1);
  opacity: 0.6;
}

hue-rotate()

Rota el matiz del color en grados:

@keyframes rainbow {
  from { filter: hue-rotate(0deg); }
  to   { filter: hue-rotate(360deg); }
}
.arcoiris {
  animation: rainbow 4s linear infinite;
}

sepia()

Da un tono vintage cálido. 0 = sin efecto, 1 = sepia total:

.foto-vintage {
  filter: sepia(0.8) contrast(1.1);
}

invert()

Invierte los colores. 1 = inversión total:

/* Modo oscuro para imágenes que no tienen versión dark */
@media (prefers-color-scheme: dark) {
  .diagrama-externo {
    filter: invert(1) hue-rotate(180deg);
    /* hue-rotate(180deg) corrige los tonos que el invert distorsiona */
  }
}

drop-shadow()

La diferencia clave con box-shadow: drop-shadow respeta la forma real del elemento, no su bounding box. Es esencial para imágenes PNG con transparencia y SVGs:

/* box-shadow: sombra en el rectángulo del elemento */
.con-box-shadow {
  box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.4);
}

/* drop-shadow: sombra que sigue la forma del contenido */
.icono-png {
  filter: drop-shadow(4px 4px 8px rgba(0, 0, 0, 0.4));
}

Encadenar filtros

Puedes combinar múltiples filtros en una sola declaración. El orden importa: se aplican de izquierda a derecha:

.foto-procesada {
  filter: brightness(1.1) contrast(1.2) saturate(1.3) hue-rotate(10deg);
}

Transición y animación de filtros

.tarjeta img {
  filter: grayscale(1) brightness(0.8);
  transition: filter 0.4s ease;
}
.tarjeta:hover img {
  filter: grayscale(0) brightness(1);
}

backdrop-filter: filtra lo que hay DETRÁS

La diferencia fundamental:

  • filter afecta al elemento y su contenido.
  • backdrop-filter afecta a lo que hay detrás del elemento.

Para que sea visible, el elemento debe tener algún nivel de transparencia (background con alpha, o sin background).

Glassmorphism

.card-glass {
  background: rgba(255, 255, 255, 0.15);
  backdrop-filter: blur(12px) saturate(1.5);
  -webkit-backdrop-filter: blur(12px) saturate(1.5); /* Safari */
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 16px;
}
.navbar {
  position: sticky;
  top: 0;
  background: rgba(255, 255, 255, 0.75);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
  z-index: 100;
}
.modal-overlay {
  background: rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(6px);
}

Rendimiento

filter y backdrop-filter crean un nuevo stacking context y pueden ser costosos, especialmente blur() con valores grandes:

  • Usa will-change: filter solo en elementos que se van a animar con filter.
  • Evita backdrop-filter: blur() en áreas de alta densidad de texto o UI compleja.
  • drop-shadow() es más costoso que box-shadow porque analiza la forma del elemento.
  • En listas largas, no pongas filters en cada row.

¿Qué hemos aprendido?

  • filter aplica efectos gráficos al elemento: blur, brightness, contrast, saturate, drop-shadow…
  • drop-shadow() sigue la forma real del contenido, box-shadow no.
  • backdrop-filter filtra lo que hay detrás — ideal para glassmorphism y navbars.
  • Los filtros son animables y se pueden encadenar.

Siguiente paso

En la próxima lección veremos clip-path y masking: cómo dar formas no rectangulares a los elementos con CSS puro.