A versão curta
- Uma textura de ruído em CSS faz-se normalmente com um filtro SVG feTurbulence, embebido como uma pequena imagem data URI e repetido em mosaico sobre um gradiente.
- O baseFrequency do feTurbulence define o tamanho do grão: valores mais altos dão grão mais fino, valores mais baixos dão ruído grosso e nebuloso.
- O ruído funciona melhor sobre o gradiente num pseudoelemento, com um modo de mistura como soft-light ou overlay e pouca opacidade.
- O grão esconde as faixas do gradiente porque quebra as arestas visíveis entre tons vizinhos numa variação fina e aleatória.
- Uma imagem de ruído em mosaico é barata de desenhar, enquanto aplicar um filtro SVG ao vivo a um elemento grande, ou animá-lo, custa muito mais.
Nesta página
Uma textura de ruído em CSS é um salpico fino e aleatório sobreposto a uma cor ou gradiente para lhe dar grão. O CSS não tem uma função de ruído, por isso a fonte habitual é o SVG: o filtro feTurbulence gera o ruído, embrulhas-o num pequeno SVG, embebes isso como data URI e repetes em mosaico sobre o teu gradiente com pouca força. O resultado parece grão de película ou papel impresso, e corrige discretamente as faixas, os degraus visíveis que aparecem em gradientes grandes e suaves.
Porque é que o grão faz a cor parecer mais cara está explicado nos gradientes com grão. Este guia é a implementação.
O filtro de ruído SVG
<svg xmlns="http://www.w3.org/2000/svg" width="240" height="240">
<filter id="n">
<feTurbulence type="fractalNoise" baseFrequency="0.8" numOctaves="3" stitchTiles="stitch" />
<feColorMatrix type="saturate" values="0" />
</filter>
<rect width="100%" height="100%" filter="url(#n)" />
</svg>| Atributo | Valor aqui | O que controla |
|---|---|---|
type | fractalNoise | Grão suave e uniforme. O turbulence dá ruído mais riscado e ondulado. |
baseFrequency | 0.8 | O tamanho do grão. Cerca de 0,6 a 0,9 é grão fino; 0,1 a 0,3 é nebuloso. |
numOctaves | 3 | Camadas de detalhe. Além de cerca de 4 a diferença é difícil de ver. |
stitchTiles | stitch | Faz as arestas do mosaico coincidirem, para as repetições não terem junções. |
feColorMatrix saturate 0 | 0 | Remove a cor aleatória, deixando grão cinzento. |
Embeber o ruído como data URI
Um ficheiro à parte funciona, mas embeber poupa um pedido e mantém o efeito num só sítio. Num data URI, os carateres que significam algo nos URL têm de ser codificados: < passa a %3C, > passa a %3E, # passa a %23 e % passa a %25. Usa aspas simples dentro do SVG para não chocarem com as aspas duplas à volta do URL.
:root {
--noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}# como %23 é a razão habitual de não mostrar nada no Firefox.Sobrepor o ruído a um gradiente
Põe o ruído num pseudoelemento por cima do gradiente e controla-o com dois botões: um modo de mistura, que decide como o grão cinzento se mistura com a cor por baixo, e a opacidade, que decide a sua força. O soft-light mantém as cores limpas e é o mais suave; o overlay acrescenta mais contraste. O pointer-events: none impede a camada de bloquear cliques.
.grain {
position: relative;
isolation: isolate;
background: linear-gradient(135deg, #1e1b4b, #7c3aed 55%, #f472b6);
}
.grain::after {
content: "";
position: absolute;
inset: 0;
z-index: -1;
background-image: var(--noise);
mix-blend-mode: soft-light;
opacity: 0.45;
pointer-events: none;
}.grain fica nítido.Se preferires um único elemento sem pseudoelemento, lista o ruído primeiro em background-image e define background-blend-mode: soft-light, normal. Perdes o botão de opacidade separado, por isso incorpora a força no SVG, por exemplo com opacity='0.5' no rect.
Quanto grão é suficiente
- 1
Começa ténue
Começa com
opacity: 0.3esoft-light. Deves mal reparar nele à distância de um braço. - 2
Verifica a zona mais escura
As faixas vivem em esbatidos escuros e lentos. Sobe a opacidade até os degraus aí se dissolverem e pára.
- 3
Ajusta o grão ao tamanho
Os heróis de ecrã inteiro aguentam um grão ligeiramente mais grosso, cerca de 0,6. Os cartões e botões pedem grão fino, cerca de 0,9.
- 4
Verifica num telemóvel e num monitor grande
Um grão que parece certo num ecrã pode parecer pó noutro. Procura uma textura que se sinta em vez de se ver.
- 5
Verifica o texto por cima
O grão não pode reduzir a legibilidade. Se texto pequeno assenta sobre a textura, baixa a força ou mantém o texto numa zona mais calma.
Demais
- Grão visível do outro lado da sala
- As cores ficam cinzentas e sujas
- Ruído grosso e nebuloso em componentes pequenos
- As arestas do texto parecem difusas contra o salpico
Mais ou menos certo
- Grão só notado de perto
- As cores ficam limpas com soft-light
- Grão fino ajustado ao elemento
- Faixas desaparecidas, texto nítido
Desempenho do ruído em CSS
Um data URI em mosaico é barato: o navegador desenha o pequeno mosaico uma vez e repete-o, e uma camada estática é pintada uma vez. A versão cara é aplicar o filtro ao vivo a um elemento grande com filter: url(#noise), que corre o filtro sobre cada píxel sempre que a área repinta. Se animares o grão, para um aspeto de película a cintilar, desloca a camada em mosaico com transform em alguns passos aos saltos em vez de regenerar o ruído, e desliga-a para movimento reduzido.
.grain {
overflow: hidden;
}
.grain::after {
inset: -50%;
animation: flicker 0.6s steps(3) infinite;
}
@keyframes flicker {
0% { transform: translate(0, 0); }
33% { transform: translate(-3%, 2%); }
66% { transform: translate(2%, -3%); }
}
@media (prefers-reduced-motion: reduce) {
.grain::after { animation: none; }
}Um mosaico de ruído PNG ou WebP pré-desenhado de cerca de 128 a 256 píxeis é uma fonte igualmente boa se já tiveres um. O grão é também um ingrediente de uma família mais ampla de superfícies, do papel ao vidro, tratada na textura de fundo. É também a camada final de um gradiente de malha em CSS.
O grão está incorporado em todos os Marks da Gradiently como uma definição de material, junto com a luz e o movimento, por isso os designs feitos com um levam textura sem código nenhum.

GR·W4AX·4M
Muslin Anvil
Ver este MarkPerguntas frequentes
Como acrescento uma textura de ruído em CSS?
Embebe um SVG com um filtro feTurbulence como data URI, repete-o em mosaico num pseudoelemento sobre o teu gradiente e define um modo de mistura como soft-light com pouca opacidade.
Porque não aparece o meu data URI de ruído SVG?
Normalmente por um caráter sem codificar. No data URI, codifica # como %23, % como %25 e os parênteses angulares como %3C e %3E, e usa aspas simples dentro do SVG.
O grão corrige as faixas nos gradientes?
Sim, na maioria dos casos. A variação fina e aleatória quebra as arestas duras entre tons vizinhos, por isso o olho deixa de ver degraus.
Que baseFrequency devo usar para o grão?
Cerca de 0,6 a 0,9 dá grão fino, tipo película. Valores mais baixos, como 0,2, dão ruído grande e nebuloso.
O ruído em CSS é mau para o desempenho?
Uma pequena imagem de ruído em mosaico é barata. Os filtros SVG ao vivo em elementos grandes e o ruído regenerado constantemente é que custam mais.
Escrito pela Gradiently
A equipa por trás da Gradiently, uma ferramenta de design construída em torno dos Marks: gradientes vivos que fazem tudo o que crias parecer teu.
Ver o nosso perfil


