Como criar degradê com risco no CSS: o guia prático
O degradê com risco (ou gradiente com stroke) é uma técnica relativamente recente no CSS que permite aplicar uma transição de cores na borda de um elemento. O problema é que, por anos, simplesmente não funcionou direito no navegador. Você tentava usar background-clip: text para texto e depois achava que border-image resolveria a borda, mas o resultado era frustrante. Bordas semigradientes, alinhamento errado, quebras em telas pequenas — o costume.
O que é degrade com risco
Na prática, degrade com risco é a aplicação de um gradiente linear ou radial diretamente na borda de um elemento HTML. Diferente do degradê de preenchimento (background), que você vê todo dia em sites, a versão com risco exige um truque porque o CSS padrão não tem uma propriedade única chamada stroke-gradient. O que existe são contornar bordas com imagem via border-image ou usar o caminho mais indireto com pseudo-elementos e mask. O método mais viável atualmente combina três coisas: um gradiente no background de um pseudo-elemento absoluto, um mask-image para revelar apenas a borda, e ajuste de padding no elemento filho para empurrar o conteúdo para o centro. Vou mostrar o código em seguida, mas antes preciso falar de um problema específico que encontrei.
Um problema real que ninguém menciona
Em 2023, trabalhei em um projeto onde precisávamos de degrade com risco em cards de preço para um e-commerce. O desafio era que os cards precisavam funcionar em Android com WebView e em Safari iOS 15, que ainda estava presente em uso. O primeiro código que escrevi usava -webkit-mask-composite e funções de mask que o Safari simplesmente ignorava. O resultado era uma borda gradiente que desaparecia totalmente no iOS, enquanto no Chrome aparecia perfeito. A solução que funcionou foi trocar a abordagem de mask por uma camada extra. Em vez de aplicar mask no pseudo-elemento, eu criei um ::before com o gradiente e um ::after branco (ou na cor do fundo) menores por dentro, criando o efeito de "borda" apenas pela sobreposição. Funcionou em todos os navegadores relevantes. Custou duas horas a mais de desenvolvimento, mas eliminou testes infinitos de rendering.
O código que realmente funciona
Esta é a estrutura base. Você pode copiar e adaptar:
.card-gradient-border {
position: relative;
background: #ffffff;
border-radius: 16px;
padding: 3px; /* essa é a espessura do risco */
}
.card-gradient-border::before {
content: "";
position: absolute;
inset: 0;
border-radius: 16px;
background: linear-gradient(135deg, #6366f1, #a855f7, #ec4899);
z-index: -1;
}
.card-gradient-border .content {
background: #ffffff;
border-radius: 13px; /* levemente menor que o pai */
padding: 24px;
}
A lógica é simples: o container tem padding: 3px e um pseudo-elemento atrás com o gradiente. O conteúdo interno é uma div com fundo branco e border-radius ligeiramente menor, que cobre o centro do gradiente, restando apenas as 3px de borda colorida ao redor. Se quiser um degradê com risco que realmente segue a curva do elemento sem cortar nos cantos, ajuste o inset do pseudo-elemento para -3px (ou o valor negativo correspondente ao seu padding) para que o gradiente se estenda um pouco além da borda e evite vazamentos visuais.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Quando usar border-image ao invés disso
O border-image com gradiente é tecnicamente possível usando border-image-source: linear-gradient(...), mas tem uma limitação enorme: ele funciona apenas combordas retas e sólidas nas esquinas. Esquinas arredondadas ficam travadas no primeiro canto definido no gradiente, sem interpolacao. Se o seu design pede border-radius real com gradiente, abandone border-image e vá para a abordagem de pseudo-elemento descrita acima. Por outro lado, se você precisa de degrade com risco em ícones SVG com stroke, aí sim o caminho é outro. SVG suporta gradientes em stroke nativamente com <linearGradient> e url(#id). Nesse caso, não use CSS, use SVG direto no markup. É mais limpo e não quebra em nenhum navegador.
Pegadinhas comuns
A primeira pegadinha é o z-index. Se o pseudo-elemento não tiver z-index: -1 explícito, ele pode subir e cobrir o conteúdo em certos contextos de stacking, especialmente dentro de containers com transform ou filter. A segunda é o border-radius desigual entre o pseudo-elemento e o conteúdo. Se a diferença for muito grande, a borda parece desproporcional em algumas áreas. Mantenha uma diferença de 2-4px entre os raios, nada mais. Uma terceira pegadinha que pega até quem já trabalha com isso: elementos com box-shadow dentro do container gradiente. A sombra pode aparecer por baixo do pseudo-elemento e criar um efeito duplo estranho. Nesse caso, mova o shadow para o pseudo-elemento também ou remova-o.
Performance e alternativas
A técnica de pseudo-elemento é leve. Duas divs e um gradiente CSS não pesam quase nada. O problema aparece quando você aplica isso em listas com dezenas de itens — aí cada card duplica o DOM e o navegador precisa compilar cada pseudo-elemento separadamente. Em listas longas, considere usar will-change: transform no container ou, se a qualidade visual não for crítica, optar por uma borda CSS sólida com cor uniforme. Não adianta forçar degrade com risco em todo lugar se o custo visual não justificar o ganho. Para quienes trabalham com frameworks como React ou Vue, a técnica se repete como componente. Eu recomendo envolver a lógica em um componente reutilizável que aceite gradient-stops, angle, thickness e border-radius como props. Dessa forma você não replica o CSS em cada arquivo e mantém consistência no design system.
Quando o degradê com risco não vai funcionar
Em print stylesheets, por exemplo. Navegadores não renderizam pseudo-elementos em impressão por padrão, então o risco gradiente simplesmente some. Se o projeto exige que o card tenha borda colorida na versão impressa, você precisa de um media query dedicado com border sólido como fallback. Ignore isso e o resultado no papel será um card sem nenhuma borda visível. Também não use essa técnica em elementos que precisam de alto contraste para acessibilidade automática. O degradê por si só não garante contraste suficiente contra fundos claros ou escuros. Teste sempre com ferramentas de verificação de contraste, especialmente se o gradiente passar por tons claros.
Resumo rápido
O degrade com risco via pseudo-elemento é a abordagem mais estável hoje. Evite border-image para bordas arredondadas. Use SVG quando for stroke em ícone. E lembre-se do problema do z-index e do border-radius desproporcional — são os dois erros que mais passam despercebidos e causam bugs visuais difíceis de rastrear.