Backdrop-filter (blur) n'a aucun effet sur .menu-panel, bien que la transparence du fond fonctionne

Je personnalise un thème personnalisé existant depuis longtemps et je voulais donner au menu hamburger/barre latérale (.menu-panel) le même effet translucide et flouté qui fonctionne déjà très bien sur .d-header. La transparence fonctionne, mais le flou non — et je souhaite signaler ce point en tant que retour d’expérience, car plusieurs aspects de la façon dont les styles principaux gèrent ce composant ont rendu la tâche plus difficile que prévu.

Ce que j’essaie d’obtenir

Un panneau de menu semi-transparent avec un backdrop-filter: blur() derrière, afin que le contenu de la page reste perceptible à travers le panneau, similaire à l’effet de verre dépoli utilisé par de nombreuses applications natives. L’effet de transparence et le flou sont importants pour moi — la transparence sans flou a l’air brouillon sur les listes de sujets chargées.

Ce qui fonctionne déjà

Sur .d-header, il suffit de ceci et cela fonctionne de manière fiable (testé sur iOS Safari et Chrome bureau) :

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

Ce qui ne fonctionne pas

La même recette appliquée à .menu-panel me donne la transparence, mais jamais le flou, sur 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;
}

J’ai essayé plusieurs choses pour faire apparaître le flou, sans succès :

  • Ajouter !important aux déclarations backdrop-filter/-webkit-backdrop-filter elles-mêmes.
  • Forcer une couche de compositing dédiée avec transform: translateZ(0) combiné à overflow: hidden (un contournement courant pour d’autres problèmes de backdrop-filter sur Safari) — cela n’a fait aucune différence ici, donc je l’ai retiré plutôt que de garder un hack qui ne se justifiait pas.
  • J’ai confirmé que je cible le bon élément : selon menu-panel.scss, l’arrière-plan opaque est défini directement sur .menu-panel (et non sur un élément enfant comme .panel-body), ce que j’avais initialement mal compris avant de corriger.

Si quelqu’un sait pourquoi .menu-panel se comporte différemment de .d-header ici, ou a une recette qui fonctionne, je serais ravi de l’entendre.

Deuxième problème : arrière-plans codés en dur sur les lignes individuelles du menu

Même avec l’arrière-plan du panneau rendu transparent, plusieurs éléments à l’intérieur restent pleins, car le cœur définit leur arrière-plan directement plutôt que via l’arrière-plan du panneau lui-même :

  • .user-notifications-list .read et .bookmark — les notifications lues et les signets dans le menu utilisateur reçoivent background-color: var(--secondary) directement, de sorte que chaque ligne apparaît comme un bloc opaque flottant sur le panneau translucide.
  • .hamburger-panel .sidebar-footer-wrapper .sidebar-footer-container — le pied de page du profil/connexion en bas de la barre latérale a le même problème.

Je peux (et l’ai fait) remplacer ces styles dans mon thème, mais cela implique de traquer chaque var(--secondary) codé en dur dans menu-panel.scss un par un, et cela cassera à nouveau la prochaine fois que le cœur ajoutera un nouvel élément avec le même motif. Cela aiderait beaucoup si ces éléments renvoyaient par défaut à une variable CSS personnalisée, par exemple quelque chose comme --d-menu-panel-background avec une valeur par défaut de var(--secondary), afin qu’un thème n’ait besoin que de redéfinir une seule variable pour rendre le panneau entier — y compris ses lignes — uniformément transparent, au lieu de traquer des sélecteurs individuels.

Je suis prêt à partager des captures d’écran avant/après si cela peut aider, et à tester toute correction suggérée de mon côté.

1 « J'aime »

Question de suivi : le même manque de transparence/effet de flou visible se manifeste désormais sur un autre élément qui partage le chemin de style .menu-panel — le champ de saisie du menu déroulant de recherche de l’en-tête (.search-input-wrapper, faisant partie du menu de recherche glimmer).

Recette (motif identique à celui de .d-header qui fonctionne, et à .menu-panel ci-dessus) :

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

Ce qui s’affiche correctement : la bordure fine (box-shadow) et le border-radius s’affichent exactement comme prévu — le sélecteur cible donc bien le bon élément et la règle est appliquée, sans être silencieusement écrasée.

Ce qui ne s’affiche pas : aucune transparence visible et aucun flou visible de ce qui se trouve derrière le champ, même symptôme que pour .menu-panel (panneau latéral/panneau hamburger) signalé plus haut. .d-header, qui utilise les trois mêmes lignes littérales (background-color via color-mix, -webkit-backdrop-filter, backdrop-filter), continue de fonctionner correctement.

Cela me fait de plus en plus soupçonner que le problème ne concerne pas .menu-panel lui-même, mais quelque chose que ces éléments de type menu déroulant/superposition partagent (un contexte de superposition créé ailleurs dans le noyau, une couche de composition qui n’est pas un bloc contenant approprié pour backdrop-filter, ou similaire) — plutôt que quelque chose lié à notre propre sélecteur ou à nos valeurs de propriétés, puisque les trois mêmes propriétés CSS se comportent différemment selon l’élément du noyau auquel elles sont attachées.

Quelqu’un a-t-il rencontré un problème de rendu de backdrop-filter/fond translucide spécifiquement sur le menu déroulant de recherche ou d’autres superpositions de la famille .menu-panel, alors que la même recette fonctionne sur l’en-tête ?

Le problème est que chaque notification de lecture possède une couleur d’arrière-plan distincte, qui doit également être remplacée. Cela devrait aider en complément de vos autres modifications :

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

De même, pour le champ de recherche, une couleur d’arrière-plan distincte y est appliquée et doit être supprimée :

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

Nous disposons d’un guide qui explique comment effectuer ce type de modifications CSS, ce qui pourrait vous aider : Making custom CSS changes on your site

1 « J'aime »

Merci beaucoup ! — les deux corrections ont fonctionné exactement comme décrit.

Pour ceux qui rencontrent le même problème : en plus des deux surcharges que vous avez publiées, j’avais aussi un élément .results imbriqué dans .search-menu-panel qui appliquait son propre fond opaque indépendamment de .menu-panel, ce qui nécessitait le même traitement :

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

Avec cela, plus vos deux extraits, la transparence fonctionne maintenant proprement partout — barre latérale, panneau hamburger, notifications d’accès rapide et le menu déroulant de recherche complet, y compris la liste des résultats. Le texte reste parfaitement lisible partout, donc en termes d’opacité, c’est entièrement résolu pour nous.

Le seul point qui reste en suspens est le sujet initial de ce fil de discussion : backdrop-filter/flou lui-même. Même avec tous les fonds maintenant correctement transparents, aucun de ces éléments n’affiche de flou — même symptôme qu’avant, et toujours en contraste avec .d-header, où la même recette backdrop-filter s’affiche correctement. Donc le côté transparence est résolu, mais le côté flou reste ouvert.

Merci encore pour le temps que vous avez pris à creuser cette question — c’est vraiment utile.

1 « J'aime »

D’accord, c’est un peu plus compliqué… lorsqu’un élément comme l’en-tête reçoit un backdrop-filter, il devient la racine de l’effet. Ainsi, tout élément descendant imbriqué dans cette racine (comme les panneaux de menu déroulant) ne peut flouter que ce qui se trouve à l’intérieur de cette racine… il ne peut pas voir le contenu de la page au-delà de l’en-tête, même si les panneaux s’étendent au-delà de celui-ci, donc vous n’obtenez aucun flou là-bas.

Ce que vous pouvez faire à la place, c’est utiliser un pseudo-élément sur l’en-tête pour éviter cette restriction de racine.

.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 « J'aime »

(publication supprimée par l’auteur)

1 « J'aime »