Backdrop-filter (blur) no tiene efecto en .menu-panel, aunque la transparencia del fondo sí funciona

Estoy personalizando un tema a medida que lleva tiempo en desarrollo y quería darle al menú hamburguesa/lateral (.menu-panel) el mismo aspecto translúcido y difuminado que ya funciona bien en .d-header. La transparencia funciona, pero el desenfoque no —y me gustaría señalar esto como retroalimentación, ya que un par de aspectos sobre cómo los estilos base manejan este componente lo hicieron más difícil de lo esperado.

Lo que estoy intentando lograr

Un panel de menú semitransparente con backdrop-filter: blur() detrás, de modo que el contenido de la página se insinúe a través del panel, similar al aspecto de vidrio esmerilado que usan muchas aplicaciones nativas. Tanto el efecto de transparencia como el desenfoque me importan —la transparencia sin desenfoque se ve desordenada sobre listas de temas con mucho contenido.

Lo que ya funciona

En .d-header, esto es todo lo que se necesita y funciona de manera fiable (probado en iOS Safari y Chrome de escritorio):

.d-header {
  background-color: color-mix(in srgb, var(--header_background) 50%, transparent);
  -webkit-backdrop-filter: blur(3px) saturate(1.2);
  backdrop-filter: blur(3px) saturate(1.2);
}

Lo que no funciona

La misma receta aplicada a .menu-panel me da la transparencia, pero nunca el desenfoque, en iOS Safari:

.menu-panel {
  background-color: color-mix(in srgb, var(--secondary) 85%, transparent) !important;
  -webkit-backdrop-filter: blur(6px) saturate(1.2);
  backdrop-filter: blur(6px) saturate(1.2);
  border-radius: 14px;
}

Cosas que probé para hacer que apareciera el desenfoque, ninguna de las cuales ayudó:

  • Agregar !important a las declaraciones de backdrop-filter/-webkit-backdrop-filter en sí mismas.
  • Forzar una capa de composición dedicada con transform: translateZ(0) combinado con overflow: hidden (un truco común en Safari para otros problemas de backdrop-filter) —esto no hizo ninguna diferencia aquí, así que lo eliminé de nuevo en lugar de mantener un hack que no justificaba su presencia.
  • Confirmé que estoy apuntando al elemento correcto: según menu-panel.scss, el fondo opaco se establece directamente en .menu-panel (no en un hijo como .panel-body), lo cual inicialmente tenía mal y luego corregí.

Si alguien sabe por qué .menu-panel se comporta de manera diferente a .d-header aquí, o tiene una receta que funcione, me encantaría saberlo.

Segundo problema: fondos codificados en las filas individuales del menú

Incluso con el fondo del propio panel hecho transparente, varias cosas dentro de él aún se renderizan sólidas, porque el núcleo establece su fondo directamente en lugar de a través del fondo del propio panel:

  • .user-notifications-list .read y .bookmark —las notificaciones leídas y los marcadores en el menú de usuario obtienen background-color: var(--secondary) directamente, por lo que cada fila aparece como un bloque opaco flotando sobre el panel translúcido.
  • .hamburger-panel .sidebar-footer-wrapper .sidebar-footer-container —el pie de perfil/inicio de sesión en la parte inferior de la barra lateral tiene el mismo problema.

Puedo (y lo hice) sobrescribir estos en mi tema, pero significa buscar cada var(--secondary) codificado en menu-panel.scss uno por uno, y volverá a romperse la próxima vez que el núcleo agregue un nuevo elemento con el mismo patrón. Ayudaría mucho si estos cayeran en una propiedad personalizada de CSS en su lugar, por ejemplo, algo como --d-menu-panel-background con un valor predeterminado de var(--secondary), para que un tema solo necesite redefinir una variable para hacer que todo el panel —incluidas sus filas— sea consistentemente transparente, en lugar de perseguir selectores individuales.

Estoy feliz de compartir capturas de pantalla de antes/después si es útil, y de probar cualquier corrección sugerida en mi extremo.

1 me gusta

Pregunta de seguimiento: la misma falta de transparencia/difuminado visible ahora también aparece en otro elemento que comparte la ruta de estilo .menu-panel: el campo de entrada del menú desplegable de búsqueda de la cabecera (.search-input-wrapper, parte del menú de búsqueda de glimmer).

Receta (patrón idéntico al de .d-header que funciona, y al de .menu-panel anterior):

.search-menu .search-input-wrapper {
  background: color-mix(in srgb, var(--header_background) 85%, transparent) !important;
  -webkit-backdrop-filter: blur(6px) saturate(1.2);
  backdrop-filter: blur(6px) saturate(1.2);
  border-radius: 14px;
  box-shadow: 0 0 0 1px var(--primary-low-mid);
  overflow: hidden;
}

.search-menu .search-input {
  background: transparent !important;
}

Lo que se renderiza correctamente: el borde fino (box-shadow) y el border-radius aparecen exactamente como se esperaba, por lo que el selector está coincidiendo con el elemento correcto y la regla se está aplicando, sin ser anulada silenciosamente.

Lo que no se renderiza: no hay transparencia visible ni difuminado visible de lo que hay detrás del campo, el mismo síntoma que .menu-panel (panel lateral/menú hamburguesa) reportado anteriormente. .d-header, que utiliza las mismas tres líneas literales (background-color mediante color-mix, -webkit-backdrop-filter, backdrop-filter), sigue funcionando sin problemas.

Esto me hace sospechar cada vez más que no se trata de algo específico de .menu-panel en sí, sino de algo que comparten estos elementos de tipo menú desplegable/superposición (un contexto de apilamiento creado en otro lugar del núcleo, una capa de composición que no es un bloque contenedor adecuado para backdrop-filter, o algo similar), en lugar de algo relacionado con nuestro propio selector o valores de propiedad, ya que las mismas tres propiedades CSS se comportan de manera diferente dependiendo de a qué elemento del núcleo estén unidas.

¿Alguien ha encontrado que backdrop-filter/fondo translúcido no se renderice específicamente en el menú desplegable de búsqueda u otras superposiciones de la familia .menu-panel, a pesar de que la misma receta funciona en la cabecera?

El problema es que cada notificación leída tiene un color de fondo diferente, que también debe sobrescribirse. Esto debería ayudar además de tus otros cambios

.user-menu .quick-access-panel .read {
  background: transparent;
}

De manera similar, con la entrada de búsqueda, se aplica un fondo separado allí que debe eliminarse:

.search-menu .search-input, .search-menu-container .search-input {
  background: transparent;
}

Tenemos una guía que explica cómo realizar cambios de CSS como estos, que puede ser de ayuda, Making custom CSS changes on your site

1 me gusta

¡Muchas gracias! — ambas correcciones funcionaron exactamente como se describía.

Para quien se encuentre con el mismo problema: además de las dos sobrescripciones que publicaste, también tenía un elemento .results anidado dentro de .search-menu-panel que pintaba su propio fondo opaco de forma independiente a .menu-panel, y necesitaba el mismo tratamiento:

.search-menu-panel .results {
  background: transparent !important;
}

Con eso más tus dos fragmentos, la transparencia ahora funciona limpiamente en todas partes: la barra lateral, el panel de hamburguesa, las notificaciones de acceso rápido y el desplegable de búsqueda completo, incluida la lista de resultados. El texto sigue siendo perfectamente legible en todo momento, así que, en cuanto a opacidad, el problema está completamente resuelto para nosotros.

La única pieza que sigue pendiente es el tema original de este hilo: backdrop-filter/blur en sí mismo. Incluso con todos los fondos ahora correctamente transparentes, ninguno de estos elementos muestra ningún desenfoque: mismo síntoma que antes, y en contraste con .d-header, donde la misma receta de backdrop-filter se renderiza sin problemas. Así que el lado de la transparencia está resuelto, pero el lado del desenfoque sigue abierto.

Gracias de nuevo por tomarte el tiempo para profundizar en esto; ha sido genuinamente útil.

1 me gusta

Vale, esto es un poco más complicado… cuando un elemento como la cabecera recibe un backdrop-filter, se convierte en la raíz para el efecto. Por lo tanto, cualquier elemento descendiente anidado dentro de esa raíz (como los paneles desplegables) solo puede aplicar el desenfoque a lo que está dentro de esa raíz… no puede ver el contenido de la página más allá de la cabecera, aunque los paneles se extiendan más allá de ella, por lo que no se aplica ningún desenfoque en esa zona.

Lo que puedes hacer en su lugar es usar un pseudoelemento en la cabecera para evitar esta restricción de la raíz.

.d-header {
  position: relative;
  isolation: isolate;
  background-color: transparent;

  &::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background-color: color-mix(in srgb, var(--header_background) 70%, transparent);
    backdrop-filter: blur(12px);
    pointer-events: none;
  }
}

.menu-panel {
  background-color: color-mix(in srgb, var(--secondary) 70%, transparent);
  backdrop-filter: blur(12px);
}

.user-menu .quick-access-panel .read {
  background: transparent;
}
1 me gusta

(publicación eliminada por el autor)

1 me gusta