Guia completo de sombras CSS: box-shadow, drop-shadow e text-shadow explicados

Domine as três técnicas de sombra CSS — sintaxe, parâmetros, diferenças de renderização, padrões reais e implicações de performance.

~15 min de leitura Feb 2025

Sombras são uma das ferramentas mais simples no CSS, mas a maioria dos tutoriais apenas arranha a superfície. Este guia cobre os três mecanismos em profundidade — sintaxe, parâmetros, diferenças de renderização, casos de uso reais e implicações de performance — para que você sempre escolha a técnica certa.

Por que o CSS tem três propriedades de sombra?

Cada mecanismo de sombra existe para resolver um problema diferente. Eles surgiram em momentos distintos da história do CSS e têm alvos de renderização fundamentalmente diferentes:

  • box-shadow — sombras para caixas retangulares (o box model CSS). Disponível desde o CSS 2.1, padronizado no CSS3.
  • filter: drop-shadow() — sombras que seguem a forma visível real de um elemento, incluindo transparência. Parte da especificação CSS Filter Effects Level 1.
  • text-shadow — sombras aplicadas diretamente aos contornos de glifos. Tecnicamente a mais antiga das três, introduzida no CSS 2, brevemente removida e re-padronizada no CSS3.

A confusão surge porque as três produzem o que o olho humano percebe como "uma sombra", mas o motor de renderização as trata em fases completamente diferentes do pipeline de pintura.

⚡ Regra prática

Use box-shadow para elementos de UI com fundos sólidos. Use drop-shadow para PNGs, SVGs ou qualquer coisa com transparência. Use text-shadow exclusivamente em texto.

box-shadow: o cavalo de batalha

Desenha uma ou mais sombras atrás (ou dentro) do border box de um elemento — a propriedade de sombra mais versátil e amplamente utilizada.

Sintaxe

box-shadow: [inset] offset-x offset-y [blur-radius] [spread-radius] color;

Cada valor faz exatamente uma coisa:

Parâmetro Padrão O que controla
insetomitido (externo)Desenha a sombra dentro do elemento em vez de atrás
offset-xobrigatórioDistância horizontal. Positivo = direita, negativo = esquerda
offset-yobrigatórioDistância vertical. Positivo = baixo, negativo = cima
blur-radius0Quantidade de desfoque gaussiano. Maior = mais suave e difuso
spread-radius0Expande (+) ou contrai (–) a sombra antes do desfoque
colorcurrentColorCor da sombra — sempre use rgba() ou hsla() para realismo

O spread radius: o parâmetro subutilizado

A maioria dos desenvolvedores usa offset + blur e para por aí. O spread radius desbloqueia uma classe de efeitos completamente diferente. Com spread: 0 e blur: 0 torna-se uma borda CSS perfeita e empilhável que não afeta o layout:

/* Layered outline rings — no layout impact */
box-shadow:
  0 0 0 4px rgba(201,184,154,.4),
  0 0 0 8px rgba(201,184,154,.1);

Com spread negativo você pode transformar uma sombra difusa em uma direcional que aparece apenas abaixo de um elemento:

/* Shadow only at the bottom — more realistic */
box-shadow: 0 12px 24px -8px rgba(0,0,0,.6);

Exemplos ao vivo

4px 4px 8px rgba(0,0,0,.7)
0 0 0 4px accent
inset 0 4px 12px
0 2px 4px + 0 8px 24px + ring
0 0 24px + 0 0 48px
light + dark inset pair
backdrop-blur + shadow

Sombras múltiplas: a ordem importa

Você pode empilhar um número ilimitado de sombras com uma lista separada por vírgulas. O renderizador as processa da frente para trás — a primeira sombra da lista fica no topo. Isso permite combinar sombras ambientes e direcionais para profundidade natural em temas claro e escuro.

/* Three-layer system used in serious design systems */
box-shadow:
  0 1px 2px rgba(0,0,0,.3),    /* close shadow: sharp, small */
  0 4px 16px rgba(0,0,0,.25),  /* mid shadow: soft ambient */
  0 0 0 1px rgba(255,255,255,.05); /* subtle highlight ring */

Sombras inset: profundidade e estados pressionados

A palavra-chave inset move a sombra para dentro da borda do elemento. A direção do offset se inverte intuitivamente: um offset Y positivo coloca a sombra ao longo da borda interna superior, como se a luz viesse de cima. Essencial para botões pressionados, inputs em relevo e neumorfismo:

/* Input focus state — depth without a visible border */
input:focus {
  box-shadow:
    inset 0 2px 6px rgba(0,0,0,.5),
    0 0 0 2px rgba(201,184,154,.4);
}
Ferramenta gratuita Gerador Box Shadow Ajuste os parâmetros e copie o CSS pronto para produção

filter: drop-shadow() — sombras que seguem a forma

filter: drop-shadow() não é uma propriedade — é uma função de filtro CSS. Os filtros são aplicados após a pintura, operando nos pixels finalmente renderizados de um elemento e seus descendentes. Essa distinção tem duas consequências importantes:

  • A sombra segue o contorno visível real, respeitando a transparência alpha em PNGs e a forma dos caminhos SVG.
  • O filtro afeta toda a subárvore, incluindo os filhos. Isso significa que funciona automaticamente em grupos de elementos.

Sintaxe

filter: drop-shadow(offset-x offset-y blur-radius color);

Atenção: sem spread-radius e sem palavra-chave inset. A especificação os omitiu deliberadamente. Se precisar de spread em uma sombra que segue a forma, empilhe duas chamadas drop-shadow() com raios de desfoque diferentes.

Onde box-shadow falha e drop-shadow brilha

Imagine um logo PNG transparente sobre um fundo colorido. Aplique box-shadow e você obterá uma sombra retangular ao redor do bounding box invisível — a sombra vaza nas áreas transparentes. Aplique drop-shadow() e a sombra abraça a forma visível real do logo.

A mesma lógica se aplica a:

  • Elementos SVG — caminhos, polígonos, formas compostas
  • CSS clip-path — a sombra segue o limite do clip
  • Elementos rotacionados ou transformados — a sombra segue corretamente a forma pós-transformação
  • Grupos de componentes — um filtro no pai cria sombra em todos os filhos como unidade
/* SVG icon with proper shadow */
.icon-wrapper {
  filter: drop-shadow(0 4px 8px rgba(0,0,0,.6));
}

/* PNG logo — shadow follows logo shape, not its bounding box */
.logo {
  filter: drop-shadow(2px 4px 12px rgba(0,0,0,.5));
}

/* Stacked for a glow effect on an irregular shape */
.neon-svg {
  filter:
    drop-shadow(0 0 6px rgba(201,184,154,.8))
    drop-shadow(0 0 20px rgba(201,184,154,.4));
}

O compromisso-chave: contexto de empilhamento

Aplicar filter cria um novo contexto de empilhamento e uma nova camada de composição. Normalmente tudo bem, mas significa que o elemento não pode mais se sobrepor corretamente a outras camadas de composição — o que ocasionalmente causa problemas de z-index. Se isso ocorrer, considere se box-shadow pode aproximar o efeito.

Ferramenta gratuita Gerador de Filtros CSS Combine drop-shadow com blur, brilho e saturação — pré-visualização

text-shadow: profundidade tipográfica

text-shadow é aplicado exclusivamente aos contornos de glifos do texto — não ao box do elemento. É pintado na mesma fase que o texto, atrás dos glifos, sendo a escolha certa quando se deseja profundidade ou legibilidade em elementos tipográficos.

Sintaxe

text-shadow: offset-x offset-y [blur-radius] color;

Comparado ao box-shadow, não há spread-radius nem inset. Sombras múltiplas são separadas por vírgulas, com a mesma ordem frente-para-trás.

Exemplos ao vivo

Heading
2px 2px 4px rgba(0,0,0,.8)
Neon
0 0 10px + 0 0 30px
Emboss
light + dark offset pair
Retro
hard double offset

Casos de uso comuns

Legibilidade sobre imagens: Um sutil text-shadow: 0 1px 3px rgba(0,0,0,.6) torna o texto branco legível sobre fotografias brilhantes sem precisar de um overlay escuro.

Tipografia neon/glow: Empilhe duas sombras com offset zero e raios de desfoque crescentes. A sombra interna cria o núcleo intenso, a externa cria o brilho atmosférico:

.neon {
  color: #c9b89a;
  text-shadow:
    0 0 8px rgba(201,184,154,.9),
    0 0 24px rgba(201,184,154,.5),
    0 0 60px rgba(201,184,154,.2);
}

Letterpress / relevo: Combine uma sombra clara em cima-esquerda com uma escura em baixo-direita. A direção determina se o texto parece em relevo ou afundado:

/* Raised (light = up-left, dark = down-right) */
text-shadow: -1px -1px 0 rgba(255,255,255,.15), 1px 1px 0 rgba(0,0,0,.6);

/* Recessed (reversed) */
text-shadow:  1px  1px 0 rgba(255,255,255,.1), -1px -1px 0 rgba(0,0,0,.5);

Sombra dura (estilo retrô/quadrinhos): Sem blur, offset maior, sombras duras empilhadas:

.retro {
  text-shadow: 3px 3px 0 #7a5c38, 6px 6px 0 rgba(0,0,0,.25);
}
Ferramenta gratuita Gerador Text Shadow Crie e exporte efeitos text-shadow com pré-visualização ao vivo

Comparação lado a lado

Característicabox-shadowdrop-shadow()text-shadow
AlvoBox model do elementoForma de pixels renderizadosContornos de glifos de texto
Respeita transparênciaNão — ignora alphaSim — segue a formaN/A (somente texto)
spread-radiusSimNãoNão
Palavra-chave insetSimNãoNão
Camadas múltiplasSim, separadas por vírgulaSim, funções encadeadasSim, separadas por vírgula
Contexto de empilhamentoSem novo contextoCria novo contextoSem novo contexto
Aplica-se aos filhosNãoSim (subárvore inteira)Não
Funciona em SVGApenas bounding boxSim, por caminhoN/A
Animação CSSAnimávelAnimávelAnimável
Composição GPUFrequentemente, em camadas promovidasSim, sempreRaramente

A pergunta que determina qual usar

Pergunte-se: o elemento tem um fundo retangular e opaco? Se sim, use box-shadow — mais fácil de raciocinar e sem efeitos colaterais no contexto de empilhamento. Se não (PNG transparente, SVG, forma irregular, clip-path), use drop-shadow(). Se o alvo é texto, use text-shadow.

Receitas e padrões para produção

Sistema de elevação (estilo Material)

Em vez de hardcodar valores de sombra por todo o codebase, defina uma escala de elevação como propriedades CSS personalizadas. Isso torna a profundidade global consistente e fácil de atualizar:

:root {
  --shadow-1: 0 1px 2px rgba(0,0,0,.4);
  --shadow-2: 0 2px 6px rgba(0,0,0,.35), 0 1px 2px rgba(0,0,0,.3);
  --shadow-3: 0 4px 16px rgba(0,0,0,.3), 0 2px 4px rgba(0,0,0,.3);
  --shadow-4: 0 8px 32px rgba(0,0,0,.28), 0 4px 8px rgba(0,0,0,.25);
  --shadow-5: 0 16px 48px rgba(0,0,0,.25), 0 8px 16px rgba(0,0,0,.2);
}

.card      { box-shadow: var(--shadow-2); }
.card:hover { box-shadow: var(--shadow-4); transition: box-shadow .2s ease; }
.modal     { box-shadow: var(--shadow-5); }

Sombras coloridas

Uma das técnicas mais subutilizadas: em vez de sombras pretas, tinja a sombra com a cor dominante do elemento. Fica mais natural em temas claros e escuros e cria uma qualidade similar ao glow sem parecer agressiva:

/* Button with colored shadow matching brand color */
.btn-primary {
  background: #c9b89a;
  box-shadow: 0 4px 20px rgba(201,184,154,.4), 0 2px 6px rgba(201,184,154,.3);
}
.btn-primary:hover {
  box-shadow: 0 6px 28px rgba(201,184,154,.55), 0 3px 8px rgba(201,184,154,.4);
}

Glassmorfismo com sombra

O glassmorfismo requer uma interação cuidadosamente calibrada entre backdrop-filter, fundo translúcido, borda semi-transparente e box-shadow para separar o card do fundo:

.glass-card {
  background: rgba(255, 255, 255, 0.06);
  backdrop-filter: blur(16px) saturate(1.2);
  -webkit-backdrop-filter: blur(16px) saturate(1.2);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 16px;
  box-shadow:
    0 8px 32px rgba(0,0,0,.4),    /* ambient depth */
    inset 0 1px 0 rgba(255,255,255,.08); /* top highlight */
}
🔧

PixCode Glassmorphism Generator exporta o CSS completo incluindo prefixos vendor.

Anéis de foco com box-shadow

Substituir o outline padrão do navegador por box-shadow dá controle total sobre o estilo mantendo a acessibilidade. O truque é usar uma sombra apenas de spread com blur 0:

:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px var(--bg),         /* gap between element and ring */
    0 0 0 4px rgba(201,184,154,.7); /* visible ring */
}

Neumorfismo

O neumorfismo usa pares de sombras inset e outer derivadas da cor de fundo. O elemento, a sombra e o fundo devem usar tons estreitamente relacionados — contraste extremo quebra a ilusão:

/* Element bg = slightly lighter than page bg */
.neumorphic {
  background: #1c1c1c;
  border-radius: 16px;
  box-shadow:
     8px  8px 16px #0a0a0a,   /* dark shadow: down-right */
    -8px -8px 16px #2e2e2e;   /* light shadow: up-left */
}
.neumorphic.pressed {
  box-shadow:
    inset  4px  4px 10px #0a0a0a,
    inset -4px -4px 10px #2e2e2e;
}

Considerações de performance

Sombras são uma das operações de renderização com que os desenvolvedores mais se preocupam, frequentemente sem razão. Veja o que realmente acontece:

✓ Caminhos rápidos

box-shadow em camadas de composição GPU (position:fixed, will-change:transform). filter: drop-shadow() é sempre acelerado por GPU. Animar box-shadow via transições CSS em elementos promovidos.

✗ Caminhos lentos

Animar box-shadow em elementos não promovidos aciona layout + paint em cada frame. Raios de blur grandes em filter: drop-shadow() são custosos. text-shadow com blur muito grande em muitos elementos.

Ao animar sombras

O padrão mais seguro para sombras animadas (elevações no hover, estados de carregamento) é promover o elemento primeiro e depois transicionar a sombra:

.card {
  will-change: transform;         /* promote to compositing layer */
  transform: translateZ(0);       /* trigger layer in older browsers */
  transition: box-shadow .2s ease, transform .2s ease;
  box-shadow: var(--shadow-2);
}
.card:hover {
  transform: translateY(-2px);    /* move on GPU — free */
  box-shadow: var(--shadow-4);    /* re-composite — also fast */
}
⚠️ Atenção

Não aplique will-change indiscriminadamente — cada camada promovida consome memória GPU. Use apenas em elementos que realmente vão animar, e remova-o quando a animação terminar se adicionado via JavaScript.

Performance: blur-radius vs spread-radius

Aumentar blur-radius é mais custoso que aumentar spread-radius, pois o blur requer uma convolução gaussiana que escala com a área em pixels. Uma sombra com spread: 10px, blur: 2px é mais barata que spread: 0, blur: 12px para a mesma pegada visual.

Geradores de sombra interativos no PixCode.io

As três técnicas de sombra têm geradores interativos dedicados no PixCode — ajuste parâmetros com sliders, veja o resultado ao vivo e copie o CSS pronto para produção com um clique.

Perguntas frequentes

O que e CSS box-shadow? +
CSS box-shadow adiciona uma sombra rectangular atras de um elemento com a sintaxe: offset-x offset-y blur-radius spread-radius color. Pode empilhar multiplas sombras com virgulas e usar a palavra-chave inset para renderizar a sombra dentro do elemento.
Como filter drop-shadow difere de box-shadow? +
box-shadow segue o quadro rectangular ignorando pixels transparentes. filter drop-shadow traca a forma visivel real — essencial para PNGs com transparencia, SVGs e formas irregulares.
E possivel animar sombras CSS sem prejudicar o desempenho? +
Sim, mas com cuidado. Animar box-shadow dispara layout e paint em elementos nao compostos. O padrao mais seguro e animar a opacidade entre dois pseudo-elementos com as sombras.
O que e o parametro spread-radius no box-shadow? +
O spread-radius e o quarto valor do box-shadow. Um valor positivo expande a sombra alem da area de desfocagem; um negativo encolhe-a. Um spread de 0 significa que a sombra e exactamente tao grande quanto o elemento antes da desfocagem.
Quando usar text-shadow em vez de drop-shadow? +
Use text-shadow para efeitos tipograficos — legibilidade, efeitos de brilho, texto em relevo e estilos retro. Use filter drop-shadow em elementos que precisam seguir um contorno nao rectangular.
Como criar um cartao neomorfico com box-shadow? +
O neumorfismo requer duas sombras: uma mais clara que o fundo (cima-esquerda) e uma mais escura (baixo-direita). Exemplo: box-shadow: 8px 8px 16px #0a0a0a, -8px -8px 16px #2e2e2e num cartao #1c1c1c sobre fundo #0e0e0e.
Que browsers suportam box-shadow e CSS filter? +
box-shadow e suportado em todos os browsers desde 2011 (IE 9). filter drop-shadow e suportado em todos os browsers modernos desde 2013. O Internet Explorer nao suporta filter.