# Backdrop filter em CSS: vidro fosco que se mantém rápido

[Canonical HTML page](https://gradiently.design/pt-pt/guide/css-blur-background)

O vidro fosco leva três linhas de CSS e ainda assim pode fazer engasgar um bom telemóvel. Aqui ficam o código, o que custa desenhá-lo e as alternativas que mantêm as palavras legíveis quando o desfoque não chega.

## The short version

- O backdrop filter do CSS aplica efeitos como o desfoque à zona por trás de um elemento, não ao próprio elemento.
- Um elemento precisa de um fundo parcialmente transparente para o backdrop filter se ver; num fundo sólido o efeito fica escondido.
- O custo do desfoque cresce com o raio e com o tamanho da área desfocada, e volta a ser pago sempre que o conteúdo por trás se move.
- O Safari precisou do prefixo -webkit-backdrop-filter até à versão 18, por isso publicar as duas linhas continua a ser a escolha segura.
- Uma boa alternativa é um fundo mais opaco dentro de uma consulta @supports, para que o texto continue legível quando o desfoque falta.

Um **backdrop filter** em CSS aplica um efeito gráfico, normalmente desfoque, ao que está por trás de um elemento. Escreve `backdrop-filter: blur(12px)` num elemento com um fundo parcialmente transparente e a página por baixo suaviza-se, que é o aspeto de vidro fosco usado em barras de navegação, painéis e cartões. É suportado em todos os navegadores atuais. A arte está em manter a área desfocada pequena, o raio modesto e a alternativa legível.

## A receita básica de vidro fosco

Três coisas fazem o vidro: um preenchimento translúcido para o fundo se ver, o próprio desfoque e uma margem ténue para o painel ter forma. A maioria das pessoas acrescenta também um pequeno reforço de saturação, porque desfocar faz a média das cores e deixa-as mais cinzentas do que esperas.

```css
.glass {
  background: rgb(255 255 255 / 0.14);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  backdrop-filter: blur(16px) saturate(160%);
  border: 1px solid rgb(255 255 255 / 0.22);
  border-radius: 16px;
}
```

Um painel de vidro claro para uma página escura ou colorida. Mantém a linha com prefixo primeiro para que a propriedade padrão vença onde ambas são entendidas.

O vidro só parece vidro quando há algo que valha a pena desfocar por trás. Numa página cinzenta lisa, o painel limita-se a parecer escuro. Põe-no sobre uma fotografia ou um gradiente rico, como o [glassmorphism](https://gradiently.design/pt-pt/guide/glassmorphism) explica com mais profundidade.

Brasa e violeta sobre meia-noite: `radial-gradient(circle at 20% 25%, #f97316 0%, transparent 40%), radial-gradient(circle at 80% 70%, #7c3aed 0%, transparent 45%), linear-gradient(160deg, #0f172a 0%, #1e1b4b 100%)`

Um fundo com manchas de cor distintas. O desfoque transforma as manchas em luz suave por trás do painel, que é todo o objetivo do efeito.

## O que as funções de backdrop-filter podem fazer

A propriedade aceita as mesmas funções que `filter`, e podes encadeá-las numa só declaração. Aplicam-se por ordem, da esquerda para a direita, por isso `blur()` e depois `saturate()` comporta-se de forma diferente do inverso. A lista completa está na [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter).

| Função | Exemplo | Boa para |
| --- | --- | --- |
| `blur()` | `blur(12px)` | Vidro fosco, foco por trás de uma caixa de diálogo |
| `saturate()` | `saturate(160%)` | Devolver a cor depois de o desfoque a acinzentar |
| `brightness()` | `brightness(0.7)` | Escurecer uma zona carregada por trás de texto claro |
| `contrast()` | `contrast(0.8)` | Acalmar uma fotografia ruidosa sob um painel |
| `grayscale()` | `grayscale(1)` | Atenuar a página por trás de um modal |
| `none` | `none` | Desligar o efeito numa alternativa ou numa media query |

As funções que vais mesmo usar. `brightness()` abaixo de 1 costuma ser melhor ferramenta de legibilidade do que um desfoque mais pesado.

## Desempenho do backdrop filter

O desfoque é uma das coisas mais caras que um navegador desenha. Para desfocar uma região, tem de ler cada píxel por trás do elemento, amostrar os vizinhos até ao raio de desfoque e compor o resultado, e repete esse trabalho sempre que algo por trás do painel muda. Um cabeçalho fixo sobre uma página em deslocação redesenha o desfoque em cada fotograma do deslocamento.

O custo escala com dois números que controlas: a área do elemento e o raio. Um cabeçalho de 64 píxeis desfocado a 12px é barato em quase tudo. Uma sobreposição de ecrã inteiro desfocada a 40px sobre um vídeo pode perder fotogramas num telemóvel de gama média. O panorama mais amplo está no [desempenho dos gradientes em CSS](https://gradiently.design/pt-pt/guide/css-gradient-performance).

### Lento

- Desfocar toda a janela por trás de um modal
- Raios de 30px ou mais
- Animar o raio de desfoque ao abrir e fechar
- Painéis de vidro dentro de painéis de vidro
- Desfoque sobre vídeo em reprodução automática

### Rápido

- Desfocar só a barra, cartão ou painel que precisa
- Raios entre 8px e 20px
- Fazer surgir a opacidade do painel, com o desfoque fixo
- Uma só camada de vidro, preenchimentos sólidos lá dentro
- Desfoque sobre imagens estáticas e gradientes

> **Mede num telemóvel real** Nas ferramentas de programador do Chrome, abre o painel Rendering, liga o paint flashing e desloca. Se o vidro pisca em cada fotograma e o painel Performance mostra fotogramas perdidos, reduz a área ou o raio antes de mais nada.

## Porque é que o backdrop-filter não funciona

Quando o desfoque parece não fazer nada, a causa é quase sempre uma de uma lista curta.

1. **Confirma que o fundo é transparente** Um `background: #fff` sólido cobre por completo o fundo desfocado. Usa um valor alfa como `rgb(255 255 255 / 0.15)`.
2. **Acrescenta o prefixo do Safari** O Safari só aceita a propriedade sem prefixo a partir da versão 18. Os iPhones mais antigos ainda precisam de `-webkit-backdrop-filter`.
3. **Procura uma raiz de fundo acima** Um elemento pai com `filter`, `opacity` abaixo de 1, uma máscara ou o seu próprio backdrop filter limita o que o filho consegue ver. O filho desfoca então só esse pai, o que muitas vezes parece nenhum desfoque.
4. **Atenção aos filhos fixos** Tal como o `filter`, um backdrop filter faz do elemento o bloco contentor de filhos fixos e de posição absoluta. Um menu fixo dentro de um cabeçalho de vidro posiciona-se em relação ao cabeçalho, não à janela.
5. **Garante que há algo por trás** O desfoque sobre uma cor lisa é invisível. Desloca o painel sobre uma imagem para confirmar que funciona.

## Uma alternativa que mantém o texto legível

Os painéis translúcidos são pensados em torno do desfoque. Sem ele, um preenchimento branco a 14 por cento sobre uma fotografia carregada deixa o texto assente na própria fotografia, e o contraste desaba. Escreve primeiro a versão legível e depois melhora-a onde o navegador consegue desfocar.

```css
/* Works everywhere: opaque enough to read on its own */
.glass {
  background: rgb(15 23 42 / 0.86);
  color: #f8fafc;
}

/* Upgrade where blur is available */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass {
    background: rgb(15 23 42 / 0.45);
    -webkit-backdrop-filter: blur(14px) saturate(150%);
    backdrop-filter: blur(14px) saturate(150%);
  }
}

/* Respect people who ask for less transparency, where supported */
@media (prefers-reduced-transparency: reduce) {
  .glass {
    background: rgb(15 23 42 / 0.94);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}
```

Melhoria progressiva para o vidro. O suporte de `prefers-reduced-transparency` ainda é limitado, por isso trata esse bloco como uma cortesia e não como uma garantia.

Verifica o contraste no pior ponto por trás do painel, não na média. Um título branco sobre vidro que passa por um céu brilhante pode ficar bem abaixo das razões do [contraste de cor e acessibilidade](https://gradiently.design/pt-pt/guide/color-contrast-accessibility). Escurecer com `brightness(0.7)` costuma resolver isto com mais fiabilidade do que desfocar mais.

## Quando nem precisas de desfoque

Muito vidro fosco existe só para tornar as palavras legíveis sobre um fundo carregado. Se o fundo é teu para desenhar, um mais calmo resolve o problema sem custo de renderização. Um gradiente suave e de baixo contraste por trás de um herói não precisa de painel; vê os [fundos de herói para sites](https://gradiently.design/pt-pt/guide/website-hero-background) e os [fundos desfocados](https://gradiently.design/pt-pt/guide/blurred-background), onde o desfoque é incorporado na imagem uma vez em vez de calculado a cada fotograma.

Um herói de site largo com um título a atravessar a parte mais viva de um gradiente colorido

Palavras diretamente sobre um fundo animado: é aqui que as pessoas procuram um painel de vidro.

O mesmo herói de site em que o gradiente fica mais escuro e calmo por trás do título

O mesmo fundo a acalmar-se por trás das palavras, sem painel, sombra nem desfoque.

Esta segunda abordagem é a que o Gradiently usa para a legibilidade: um Mark sabe onde estão as palavras e move a sua região mais calma e de melhor contraste para trás delas, por isso nunca precisas de uma caixa ou de um desfoque para salvar um título.

## FAQ

### Qual é a diferença entre filter e backdrop-filter?

`filter` altera o elemento e o seu conteúdo. `backdrop-filter` altera apenas o que se vê por trás do elemento, através do seu fundo transparente.

### Porque não aparece o desfoque do meu backdrop-filter?

Normalmente o fundo do elemento é totalmente opaco, o Safari precisa do prefixo `-webkit-` ou um elemento pai com `filter`, `opacity` ou uma máscara limita o que o elemento consegue ver.

### O backdrop-filter é mau para o desempenho?

Pode ser. O custo cresce com a área desfocada e o raio e é pago de novo sempre que o conteúdo por trás se move, por isso mantém os painéis de vidro pequenos e os raios modestos.

### Ainda preciso de -webkit-backdrop-filter?

O Safari aceita a propriedade sem prefixo a partir da versão 18, mas os iPhones mais antigos continuam em uso, por isso publicar as duas linhas ainda é sensato.

### Que valor de desfoque fica melhor em vidro fosco?

Entre 8px e 20px serve a maioria das interfaces. Acrescenta `saturate()` acima de 100% para restaurar a cor que o desfoque tira.
