Glassmorphism com CSS
(É esperado que esteja rodando num navegador novo. Para ver os exemplos use a feature do browser “Ver código fonte” como um bom old schooler :) )
Estava vendo um vídeo de como fazer Glassmorphism no Photoshop e pensei: dá para fazer com CSS?
Sim, dá:
Como funciona?
Há várias níveis diferentes de Glassmorphism. Imagem via The Nielsen Norman Group
O mais básico consiste em apenas um blur no fundo, que é trivial de se implementar usando backdrop-filter: blur
. A dificuldade mesmo fica na borda.
Se for possível, a solução mais fácil é usar esse Glassmorphism Generator:
No meu caso, gerou o seguinte CSS:
|
|
Como podemos perceber, há 2 problemas:
O primeiro é essa box-shadow que tá mais pro azulado. É facilmente corrigível só mudando a cor para algo mais para o lado do preto. Tipo 0 8px 32px 0 rgba(22, 25, 57, 0.37)
.
O segundo é referente a borda. Ela é uniforme, então não dá aquela impressão de profundidade.
Aí que mora o perigo.
Primeiro, precisamos fazer um gradiente com borda. Que é possível usando border-image
.
Porém nesse caso, border-radius
não funciona. Ou melhor, funciona, mas ignora que deveria ser em volta da imagem.
Uma técnica comum para este caso é adicionar uma borda falsa usando background-image
.
Obviamente fica um lixo, porque requer que o centro seja uma cor sólida (o primeiro linear-gradient).
Mas estamos no caminho certo. A ideia é ter um elemento que crie a borda usando background-image e gradiente. Porém para tal, será um elemento INTEIRO com gradiente. Então precisamos de outro elemento que DESFAÇA esse gradiente.
Parece complicado (e é), mas podemos fazer isso usando CSS Mask.
CSS Mask
Só ilustrando, a mask
funciona similar ao Photoshop e outras ferramentas. Basicamente só mostra o que está dentro dessa máscara.
Por exemplo:
Aqui ainda estamos usando aquele mesmo retângulo de vidro, mas aplicando uma máscara com essa forma estranha (btw gerada usando SVG Shape Generator).
Também podemos aplicar contra o próprio background:
Mas acho que um dos efeitos mais legais é usar contra uma máscara com gradiente:
BTW a sintaxe do linear gradiente é um pouco enjoada. Então vou deixar mais um exemplo:
|
|
Isso diz que:
- o linear gradiente começa de baixo para cima
- só inicia a transparência a partir dos 5% iniciais da imagem (ie. joga fora os 5% iniciais)
- na metade final da imagem ela é preta, aka a máscara está full
Enfim, esse caso do gradiente é útil para ter imagens E um texto embaixo, tipo um título ou algo parecido.
Mas voltando ao problema original, vamos criar, dentro da div glass-box
uma div wrap
. Essa div wrap
também tem um pseudo elemento com um gradiente de background que será a borda. Aí o pulo do gato: usamos mask com mask-composite: exclude
que funciona com um xor, para EXCLUIR tudo que não for a falsa borda. Para isso, usamos duas “layers” na máscara: uma referente ao content-box
, e outra referente a tudo.
Para ilustração (não é o caso real), imagine que tem 2 divs: uma vermelha, ligeiramente maior, e outra verde. E onde há overlap, as cores se misturam, então onde está roxo é porque tem verde + vermelho:
Agora adaptando, o purple é removido, já que está na máscara. E a borda vermelha agora é um linear-gradient.
Final
Ficará assim:
Lembrando que para ver os códigos clique em Visualizar Código fonte no seu browser :)
Referências
- mask - CSS: Cascading Style Sheets | MDN
- Apply effects to images with CSS’s mask-image property | Articles | web.dev
- Glassmorphism CSS Generator | SquarePlanet | SquarePlanet
- Glassmorphism: Definition and Best Practices
- html - Button with transparent background and rotating gradient border - Stack Overflow
- kriptonian_ comments on Does anyone know how can I give this border gradient, with glass morphism