O backdrop-filter (blur) não tem efeito no .menu-panel, mesmo que a transparência do fundo funcione

Estou personalizando um tema customizado de longa duração e queria dar ao menu hambúrguer/lateral (.menu-panel) o mesmo visual translúcido e desfocado que já funciona bem no .d-header. A transparência funciona, mas o desfocamento não — e gostaria de reportar isso como feedback, pois alguns aspectos de como o núcleo estila esse componente tornaram a tarefa mais difícil do que o esperado.

O que estou tentando alcançar

Um painel de menu semitransparente com backdrop-filter: blur() atrás dele, para que o conteúdo da página ainda seja perceptível através do painel, semelhante ao visual de vidro fosco usado por muitos aplicativos nativos. Tanto o efeito de transparência quanto o desfocamento são importantes para mim — transparência sem desfocamento fica com uma aparência bagunçada sobre listas de tópicos movimentadas.

O que já funciona

No .d-header, é só isso e funciona de forma confiável (testado no Safari para iOS e no Chrome para 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);
}

O que não funciona

A mesma receita exata aplicada ao .menu-panel me dá a transparência, mas nunca o desfocamento, no Safari para iOS:

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

Coisas que tentei para fazer o desfocamento aparecer, nenhuma das quais ajudou:

  • Adicionar !important às declarações de backdrop-filter/-webkit-backdrop-filter em si.
  • Forçar uma camada de composição dedicada com transform: translateZ(0) combinado com overflow: hidden (um truque comum no Safari para outros problemas de backdrop-filter) — isso não fez diferença aqui, então removi novamente em vez de manter um hack que não estava valendo a pena.
  • Confirmei que estou direcionando o elemento certo: de acordo com o menu-panel.scss, o fundo opaco é definido diretamente no .menu-panel (não em um filho como .panel-body), o que eu inicialmente errei e depois corrigi.

Se alguém souber por que o .menu-panel se comporta de forma diferente do .d-header aqui, ou tiver uma receita que funcione, ficarei feliz em ouvir.

Segundo problema: fundos codificados em linhas individuais do menu

Mesmo com o fundo do próprio painel tornado transparente, várias coisas dentro dele ainda são renderizadas sólidas, porque o núcleo define seu fundo diretamente, em vez de através do fundo do próprio painel:

  • .user-notifications-list .read e .bookmark — notificações lidas e marcadores no menu do usuário recebem background-color: var(--secondary) diretamente, então cada linha aparece como um bloco opaco flutuando sobre o painel translúcido.
  • .hamburger-panel .sidebar-footer-wrapper .sidebar-footer-container — o rodapé de perfil/login na parte inferior da barra lateral tem o mesmo problema.

Eu posso (e fiz) sobrescrever isso no meu tema, mas isso significa procurar cada var(--secondary) codificado em menu-panel.scss um por um, e quebrará novamente da próxima vez que o núcleo adicionar um novo elemento com o mesmo padrão. Ajuda muito se esses elementos caíssem de volta para uma propriedade CSS personalizada, por exemplo, algo como --d-menu-panel-background com valor padrão var(--secondary), para que um tema precise redefinir apenas uma variável para tornar o painel inteiro — incluindo suas linhas — consistentemente transparente, em vez de perseguir seletores individuais.

Fico feliz em compartilhar capturas de tela do antes/depois, se for útil, e para testar qualquer correção sugerida do meu lado.

1 curtida

Pergunta de acompanhamento: a mesma falta de transparência/desfoque visível agora também aparece em outro elemento que compartilha o caminho de estilização .menu-panel — o campo de entrada do dropdown de busca do cabeçalho (.search-input-wrapper, parte do menu de busca glimmer).

Receita (padrão idêntico ao do .d-header que funciona, e ao do .menu-panel acima):

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

O que é renderizado corretamente: a borda fina (box-shadow) e o border-radius aparecem exatamente como esperado — portanto, o seletor está correspondendo ao elemento correto e a regra está sendo aplicada, sem ser silenciosamente sobrescrita.

O que não é renderizado: não há translucidez visível nem desfoque visível do que estiver atrás do campo, o mesmo sintoma relatado acima para o .menu-panel (painel lateral/hambúrguer). O .d-header, usando literalmente as mesmas três linhas (background-color via color-mix, -webkit-backdrop-filter, backdrop-filter), continua funcionando perfeitamente.

Isso me leva a suspeitar cada vez mais que o problema não é específico do próprio .menu-panel, mas de algo que esses elementos de estilo dropdown/sobreposição compartilham (contexto de empilhamento criado em outro lugar no núcleo, uma camada de composição que não é um bloco contêiner adequado para backdrop-filter, ou algo similar) — em vez de qualquer coisa relacionada ao nosso próprio seletor ou aos valores das propriedades, já que exatamente as mesmas três propriedades CSS se comportam de forma diferente dependendo de qual elemento do núcleo elas estão anexadas.

Alguém já encontrou o backdrop-filter/fundo translúcido não sendo renderizado especificamente no dropdown de busca ou em outras sobreposições da família .menu-panel, mesmo que a mesma receita funcione no cabeçalho?

O problema é que cada notificação de leitura tem uma cor de fundo diferente, que também precisa ser sobrescrita. Isso deve ajudar, além das suas outras alterações

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

Da mesma forma, com a entrada de busca, há um fundo separado aplicado lá que precisaria ser removido:

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

Temos um guia que explica como fazer alterações de CSS como essas, que pode ser útil: Making custom CSS changes on your site

1 curtida

Muito obrigado! — as duas correções funcionaram exatamente como descrito.

Para quem estiver passando pelo mesmo problema: além das duas sobrescrições que você postou, eu também tinha um elemento .results aninhado dentro de .search-menu-panel pintando seu próprio fundo opaco, independentemente de .menu-panel, o que precisava do mesmo tratamento:

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

Com isso, somado aos seus dois trechos de código, a transparência agora funciona perfeitamente em todos os lugares — barra lateral, painel do menu hambúrguer, notificações de acesso rápido e o menu suspenso de pesquisa completo, incluindo a lista de resultados. O texto continua perfeitamente legível em toda a interface, então, em termos de opacidade, isso está totalmente resolvido para nós.

A única parte que ainda está pendente é o tópico original deste thread: o próprio backdrop-filter/desfoque. Mesmo com todos os fundos agora corretamente transparentes, nenhum desses elementos exibe algum desfoque — mesmo sintoma de antes, e ainda em contraste com .d-header, onde a mesma receita de backdrop-filter renderiza sem problemas. Então, o lado da transparência foi resolvido, mas o lado do desfoque permanece em aberto.

Obrigado novamente por ter dedicado tempo a investigar isso — foi genuinamente útil.

1 curtida

Certo, isso é um pouco mais complicado… quando um elemento como o header recebe um backdrop-filter, ele se torna a raiz para o efeito. Assim, qualquer elemento descendente aninhado dentro dessa raiz (como os painéis de dropdown) só pode aplicar o desfoque ao que está dentro dessa raiz… ele não consegue ver o conteúdo da página além do header, mesmo que os painéis se estendam além dele, então não há desfoque ali.

O que você pode fazer em vez disso é usar um elemento pseudo no header para evitar essa restrição de raiz.

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

(publicação removida pelo autor)

1 curtida