A borda de baixo da janela deixa de ser um corte reto. O texto e as fotos que chegam a ela vão perdendo o foco nos últimos centímetros, como numa lente de pouca profundidade de campo: nítidos a uma altura de dedo da borda, desfeitos no rodapé da tela. Ninguém repara na peça — repara que a página parece mais cara.
O problema que ela resolve é de acabamento, não de conteúdo: numa página escura e tipográfica, a linha cortada ao meio pela borda da tela é o detalhe que mais denuncia "isto é um navegador". A faixa tira esse corte sem tirar nada da leitura, porque ninguém lê na borda.
Quando usar
- Páginas longas, escuras e tipográficas — institucional, manifesto, portfólio —, em que a rolagem é a experiência.
- Trecho de leitura corrida dentro de uma dobra (variação local): uma lista longa, um texto de fôlego.
- Junto de um menu fixo de vidro (
navegacao/nav-fixa-vidro): a página fica desfocada nas duas bordas e nítida no meio.
Quando não usar
- Dobra com conteúdo ancorado embaixo da tela — o hero com CTA no rodapé, o
hero/letreiro-marcacom a promessa embaixo. Comece o trecho depois dessas dobras; o .dsf é filho do trecho, não da página. - Página de formulário ou ferramenta, em que a pessoa precisa ver o botão de enviar na borda da tela sem rolar.
- Página clara cheia de fotos sob tinta — sem tinta, funciona; com
--dsf-tinta, a borda escura sobre papel vira mancha. - Para separar duas dobras, quem faz isso é o
efeitos/moldura-secao. Esta faixa não marca nada: ela anda com a janela.
Padrão editorial
| Slot | Regra |
|---|---|
| — | Não recebe copy. É o último filho do trecho em que vale, com cinco <span> vazios |
Uma por borda, no máximo duas por página (embaixo e, se fizer sentido, em cima).
Especificação dos assets
Nenhum.
Como usar
<link rel="stylesheet" href="componentes/efeitos/desfoque-progressivo/estilo.css">
O que se cola é isto, como último filho do elemento que embrulha as dobras — normalmente o <main>:
<main>
… as dobras da página …
<div class="dsf" aria-hidden="true">
<span class="dsf-camada"></span>
<span class="dsf-camada"></span>
<span class="dsf-camada"></span>
<span class="dsf-camada"></span>
<span class="dsf-camada"></span>
</div>
</main>
<footer>… entra nítido …</footer>
Ganchos
| Gancho | Papel |
|---|---|
.dsf |
a faixa. Último filho do trecho; sticky, altura zero |
.dsf-camada × 5 |
as camadas, vazias. O raio e a janela saem da posição (:nth-child) |
--dsf-h |
altura da faixa. Padrão: --sec-gap (ver Gotchas) |
--dsf-max |
raio da camada da borda. 14px; 10px no celular |
--dsf-tinta / --dsf-cor |
tinta opcional na borda. 0% no padrão |
.dsf--topo + --dsf-topo |
a faixa na borda de cima, recuada da altura do menu |
Variações
- Borda de cima —
.dsf--topoe o lugar de primeiro filho. Com menu fixo,--dsf-topo: var(--nav-h). - Local — o
.dsfcomo último filho de uma seção: a borda desfocada existe só enquanto ela passa. - Com tinta —
--dsf-tinta: 40%. Só em trecho de tom único.
Gotchas
- É
sticky, nãofixed, e isso é a peça inteira. Uma faixafixed(que é como a referência faz) cobre o fim da página para sempre: o texto legal do rodapé fica desfocado justamente quando a pessoa rola até ele para ler.stickycombottom:0gruda na borda enquanto o trecho passa e para quando ele acaba. Medido no preview: no fim da rolagem o.dsffica exatamente no topo do rodapé de exemplo (304px e 304px), e o rodapé chega à borda da tela nítido. O preço é estrutural: o.dsftem de ser o último filho do trecho. No meio dele, a faixa sai rolando junto com o conteúdo. - A altura é o
--sec-gap, e não um número próprio. No fim do trecho a faixa fica parada sobre os últimos--dsf-hpixels da última dobra, e dali a página não rola mais. Com a altura igual ao respiro entre dobras, esses pixels são opaddingde baixo do.sec-pad— onde não há texto. Uma faixa mais alta que o respiro deixaria as últimas linhas da última dobra desfocadas sem remédio. Quem subir--dsf-hacima do--sec-gapreabre isso. - Altura zero, camadas para fora. O
.dsfnão ocupa espaço no fluxo; as camadas saem dele para cima em posição absoluta. É o que dispensa a margem negativa que uma faixa de 160px de altura real precisaria. - Cinco camadas, não uma. Um
backdrop-filtertem um raio só. Uma camada de 14px com máscara em gradiente não desfoca "aos poucos": desfoca tudo a 14px e esmaece — no meio da faixa aparecem duas imagens sobrepostas, a nítida e a borrada. As cinco camadas (raio 1/16, 1/8, 1/4, 1/2 e cheio) têm janelas de máscara que se sobrepõem pela metade, e a passagem de um raio para o seguinte não tem degrau. - Progressão geométrica, não linear. Raios de 3-6-9-12-14px pareceriam "nítido, nítido, borrado": o olho lê desfoque em escala logarítmica.
- Não mora dentro de
[data-rv]nem de nada comfilterouopacitymenor que 1. Esses ancestrais viram raiz de backdrop, e as camadas passam a desfocar só o que está dentro deles. E o trecho não pode teroverflowdiferente devisible, senão ostickygruda nele e não na janela (MANUAL §5). - Uma linha por máscara. O
#000das máscaras é opacidade, não cor, e obin/conformidade.pysó reconhece isso na linha que dizmask-image. - Custo de pintura. Cinco passadas de
backdrop-filtersobre a largura inteira da janela, repintadas a cada quadro de rolagem. Por isso cinco e não as oito da referência (as três mais fracas dela ficam abaixo de 0,4px). O tempo de quadro não foi medido nesta leva — o painel do navegador estava oculto e orequestAnimationFrameestrangulado. Meça num celular médio antes de colocar a peça numa página já pesada.
Movimento reduzido / toque
Nada anda: a faixa só acompanha a rolagem que a pessoa fez, então prefers-reduced-motion não tem o que desligar. Quem tem o que pedir é prefers-reduced-transparency: reduce — a pessoa pedindo ao sistema menos vidro e menos desfoque, que é exatamente o que a peça é. Ali ela some (Chrome 118+). Some também na impressão. Sem backdrop-filter, as camadas não pintam nada e a borda volta a ser o corte reto de sempre.
Histórico
| Origem | Quando | O quê |
|---|---|---|
| referência: Neto Scariot | 2026-10-01 | Clone de referência, reescrito do zero |
Referência visual: a faixa de desfoque presa à borda de baixo da janela, em toda a página do portfólio — o componente "progressive blur" do Framer: oito camadas, raio de 0,08 a 10px, janelas de 12,5%, num contêiner fixed de 260px. Da referência veio a técnica das janelas sobrepostas.
Normalizações aplicadas na tradução: cinco camadas em vez de oito; sticky em vez de fixed, para parar no fim do trecho; altura igual ao --sec-gap; raio escrito como fração de um parafuso (--dsf-max) em vez de oito números; aria-hidden e pointer-events:none; prefers-reduced-transparency e @media print. Registro consolidado em projetos/referencias-externas.md.