Il filtro backdrop-filter (blur) non ha effetto su .menu-panel, anche se la trasparenza dello sfondo funziona

Sto personalizzando un tema personalizzato di lunga data e volevo dare al menu hamburger/sidebar (.menu-panel) lo stesso aspetto traslucido e sfocato che funziona già bene su .d-header. La trasparenza funziona, ma la sfocatura no — e vorrei segnalarlo come feedback, poiché alcuni aspetti del modo in cui lo stile principale gestisce questo componente lo hanno reso più difficile del previsto.

Cosa sto cercando di ottenere

Un pannello del menu semitrasparente con un backdrop-filter: blur() dietro, in modo che il contenuto della pagina sia ancora accennato attraverso il pannello, simile all’effetto vetro smerigliato utilizzato da molte app native. Sia l’effetto trasparente che la sfocatura sono importanti per me — la trasparenza senza sfocatura sembra solo disordinata su liste di argomenti affollate.

Cosa funziona già

Su .d-header, basta questo e funziona in modo affidabile (testato su iOS Safari e Chrome desktop):

.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);
}

Cosa non funziona

La stessa identica ricetta applicata a .menu-panel mi dà la trasparenza, ma mai la sfocatura, su 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;
}

Cose che ho provato per far apparire la sfocatura, nessuna delle quali ha aiutato:

  • Aggiungere !important alle dichiarazioni stesse di backdrop-filter/-webkit-backdrop-filter.
  • Forzare un layer di compositing dedicato con transform: translateZ(0) combinato con overflow: hidden (una soluzione comune per Safari per altri problemi di backdrop-filter) — questo non ha fatto alcuna differenza qui, quindi l’ho rimosso di nuovo piuttosto che mantenere un hack che non valeva la pena.
  • Ho confermato di stare targeting l’elemento giusto: secondo menu-panel.scss, lo sfondo opaco è impostato direttamente su .menu-panel (non su un figlio come .panel-body), che inizialmente avevo sbagliato e poi corretto.

Se qualcuno sa perché .menu-panel si comporta in modo diverso da .d-header qui, o ha una ricetta funzionante, sarei lieto di sentirlo.

Secondo problema: sfondi hardcoded sulle singole righe del menu

Anche con lo sfondo del pannello reso trasparente, diverse cose dentro ad esso vengono ancora renderizzate solide, perché il core imposta il loro sfondo direttamente anziché attraverso lo sfondo del pannello stesso:

  • .user-notifications-list .read e .bookmark — le notifiche lette e i segnalibri nel menu utente ricevono background-color: var(--secondary) direttamente, quindi ogni riga appare come un blocco opaco che fluttua sul pannello traslucido.
  • .hamburger-panel .sidebar-footer-wrapper .sidebar-footer-container — il footer del profilo/login in fondo alla sidebar ha lo stesso problema.

Posso (e l’ho fatto) sovrascrivere questi nel mio tema, ma significa cercare uno per uno ogni var(--secondary) hardcoded in menu-panel.scss, e si romperà di nuovo la prossima volta che il core aggiunge un nuovo elemento con lo stesso pattern. Aiuterebbe molto se questi facessero fallback a una variabile CSS personalizzata, ad esempio qualcosa come --d-menu-panel-background con valore predefinito var(--secondary), in modo che un tema abbia bisogno di ridefinire solo una variabile per rendere l’intero pannello — comprese le sue righe — coerentemente trasparente, invece di inseguire selettori individuali.

Sono felice di condividere screenshot del prima/dopo se utile, e di testare qualsiasi correzione suggerita da parte mia.

1 Mi Piace

Domanda di follow-up: la stessa mancanza di trasparenza/blur visibile ora si manifesta anche su un altro elemento che condivide il percorso di stile .menu-panel — il campo di input del menu a discesa della ricerca nell’intestazione (.search-input-wrapper, parte del menu di ricerca glimmer).

Ricetta (stesso identico pattern di quello funzionante per .d-header e di .menu-panel sopra):

.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;
}

Cosa viene renderizzato correttamente: il bordo sottile (box-shadow) e il border-radius vengono entrambi visualizzati esattamente come previsto — quindi il selettore sta abbinando l’elemento corretto e la regola viene applicata, senza essere sovrascritta silenziosamente.

Cosa non viene renderizzato: nessuna trasparenza visibile e nessun blur visibile di ciò che si trova dietro il campo, stesso sintomo di .menu-panel (pannello laterale/pannello hamburger) riportato sopra. .d-header, che utilizza le stesse identiche tre righe (background-color tramite color-mix, -webkit-backdrop-filter, backdrop-filter), continua a funzionare senza problemi.

Questo mi fa sospettare sempre di più che non si tratti di qualcosa di specifico per .menu-panel stesso, ma di qualcosa che questi elementi di tipo dropdown/overlay condividono (un contesto di impilamento creato altrove nel core, un layer di composizione che non è un blocco contenitore appropriato per backdrop-filter, o simile) — piuttosto che qualcosa legato al nostro selettore o ai valori delle proprietà, dato che le esatte stesse tre proprietà CSS si comportano in modo diverso a seconda dell’elemento core a cui sono applicate.

Qualcuno ha riscontrato che backdrop-filtri/sfondi traslucidi non vengono renderizzati specificamente sul menu a discesa della ricerca o su altri overlay della famiglia .menu-panel, anche se la stessa ricetta funziona sull’intestazione?

Il problema è che ogni notifica letta ha un colore di sfondo separato, che deve anch’esso essere sovrascritto. Questo dovrebbe aiutare, in aggiunta alle altre modifiche che hai apportato.

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

Lo stesso vale per il campo di ricerca: viene applicato un colore di sfondo separato anche lì, che dovrà essere rimosso:

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

Abbiamo una guida che spiega come apportare modifiche CSS di questo tipo, che potrebbe esserti utile: Making custom CSS changes on your site

1 Mi Piace

Grazie mille! — entrambe le correzioni hanno funzionato esattamente come descritto.

Per chiunque si imbatta nello stesso problema: oltre alle due sovrascritti che hai postato, avevo anche un elemento .results annidato dentro .search-menu-panel che dipingeva un proprio sfondo opaco indipendentemente da .menu-panel, e che necessitava dello stesso trattamento:

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

Con questo, insieme ai tuoi due snippet, la trasparenza ora funziona in modo pulito ovunque: barra laterale, pannello hamburger, notifiche di accesso rapido e l’intero menu a tendina di ricerca, inclusa la lista dei risultati. Il testo rimane perfettamente leggibile in ogni punto, quindi per quanto riguarda l’opacità la questione è ora completamente risolta per noi.

L’unico aspetto ancora aperto è l’argomento originale di questo thread: backdrop-filter/blur in sé. Anche con tutti gli sfondi ora correttamente trasparenti, nessuno di questi elementi mostra alcun effetto di sfocatura — stesso sintomo di prima, e in contrasto con .d-header, dove la stessa identica ricetta di backdrop-filter viene renderizzata correttamente. Quindi il lato trasparenza è risolto, ma quello della sfocatura resta aperto.

Grazie ancora per il tempo dedicato a indagare su questo — davvero utile.

1 Mi Piace

Giusto, la questione è un po’ più complicata… quando un elemento come l’header riceve una proprietà backdrop-filter, diventa la radice per l’effetto. Di conseguenza, qualsiasi elemento discendente annidato all’interno di quella radice (come i pannelli del menu a discesa) può sfocare solo ciò che si trova all’interno di quella radice… non può “vedere” il contenuto della pagina al di fuori dell’header, anche se i pannelli si estendono oltre di esso, quindi non si ottiene alcun effetto di sfocatura in quelle aree.

Invece, puoi utilizzare uno pseudo-elemento sull’header per evitare questa restrizione relativa alla radice.

.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 Mi Piace

(post eliminato dall’autore)

1 Mi Piace