Uma box-shadow é uma cópia da caixa do elemento, pintada atrás dela: deslocada por dois offsets, suavizada por um blur, aumentada ou encolhida por um spread e preenchida com uma única cor chapada. Esse é o modelo inteiro. box-shadow: 0 8px 24px -6px rgba(16, 18, 42, 0.16); se lê como nenhum deslocamento horizontal, 8 px para baixo, uma borda suave de 24 px, uma forma encolhida 6 px de cada lado, num índigo escuro com 16% de opacidade. A sombra não ocupa espaço no layout: nada na página se move para abrir espaço para ela.
O que cada valor faz, na ordem
As medidas são lidas pela posição, então você não pode trocá-las de lugar. A cor é a exceção: pode ficar em qualquer uma das pontas, então rgba(0, 0, 0, 0.2) 0 4px 8px é tão válido quanto a mesma lista com a cor no final.
- Offset X: positivo move a sombra para a direita, negativo move para a esquerda.
- Offset Y: positivo move para baixo, negativo para cima. É esse valor que decide onde está a sua luz imaginária.
- Blur: o quão larga é a borda suave. Opcional, vale 0 por padrão e não pode ser negativo.
- Spread: o quanto a forma da sombra é maior ou menor que a caixa. Opcional, vale 0 por padrão e pode ser negativo. Como as medidas são posicionais, você não consegue escrever um spread sem escrever um blur antes, mesmo que esse blur seja 0.
- Cor: opcional. Se você omitir, o navegador usa a cor de texto do próprio elemento, que quase nunca é o que você queria.
As medidas aceitam qualquer unidade de comprimento do CSS —px, rem, em— mas não porcentagens. Uma porcentagem invalida a declaração inteira e o navegador a descarta, que é um dos motivos mais silenciosos para uma sombra "não fazer nada".
Blur não é a distância que a sombra percorre
Esse é o valor que quase todo mundo entende errado. O raio de blur não empurra a sombra para mais longe. Ele descreve a largura da transição de sólido para transparente, e essa transição fica centrada na borda que a sombra teria. Coloque 24 px de blur e a transição cobre uns 24 px: mais ou menos metade cai para fora da forma e a outra metade avança para dentro dela. A especificação define o resultado como uma aproximação de um desfoque gaussiano com desvio padrão igual à metade do raio de blur.
Duas coisas decorrem disso. Um blur grande sem spread vaza pelos lados e por cima, e é por isso que uma sombra pensada para ficar embaixo de um card acaba cercando o card como uma auréola. E uma sombra com blur mas sem offset aparece nos quatro lados, porque metade da transição escapa em todas as direções. Isso é um brilho, não uma sombra. Útil para um focus ring, inútil para dar profundidade.
Para que o spread serve de verdade
O spread redimensiona o retângulo da sombra, e só depois o resultado é borrado. A ordem importa: primeiro inflar, depois suavizar.
O spread negativo é a correção para o vazamento acima. 0 18px 36px -14px encolhe a forma em 14 px antes de borrar, então quase nada escapa para os lados e o que sobra se lê como uma poça de sombra embaixo do elemento em vez de uma névoa em volta dele. A maioria das sombras que parecem certas numa interface real tem spread negativo na camada maior.
O spread também é como você consegue sombra em um lado só. Deixe-o negativo e perto do valor do blur, depois desloque na direção que quiser: 0 10px 8px -8px coloca sombra embaixo de um elemento e em mais lugar nenhum. E numa camada inset a direção se inverte: um spread positivo deixa a sombra interna mais grossa, porque a forma está crescendo para dentro.
Por que uma sombra sozinha sempre parece falsa
A luz real faz duas coisas ao mesmo tempo. Onde um objeto encosta numa superfície existe uma sombra de contato pequena, escura e nítida. Mais para fora existe outra bem maior, bem mais fraca e difusa. Uma única sombra de CSS pode ser fechada ou suave, nunca as duas, então ela se lê como um adesivo colado na página em vez de um objeto pousado acima dela.
A correção é empilhar camadas. Separe-as por vírgula dentro de uma mesma declaração; a primeira da lista é pintada por cima: box-shadow: 0 1px 2px rgba(16, 18, 42, 0.08), 0 8px 24px -12px rgba(16, 18, 42, 0.16);. A camada pequena e fechada faz o contato, a grande e suave faz a luz ambiente, e cada uma é fraca o bastante sozinha para que a soma continue sutil.
Ajustar isso na mão significa editar seis números e recarregar a cada tentativa, e é aí que um gerador de sombras com preview ao vivo se paga: ele mantém até quatro camadas ao mesmo tempo, deixa você editar cada uma separadamente e imprime a declaração pronta. Duas camadas costumam bastar. Duas ressalvas: o preview é uma caixa sobre um fundo chapado, não a sua página, e ele não escreve text-shadow, que leva duas ou três medidas e uma cor —sem spread, sem inset—, então o truque do spread negativo acima não vale para texto.
Por que a sua sombra fica cinza e suja
Porque ela é preto puro. Compor preto sobre uma cor puxa todos os canais na direção do zero. O matiz sobrevive, mas a intensidade da cor cai junto com a luminosidade, então a faixa sombreada sobre um fundo quente fica chapada e cinza ao lado da superfície em volta. A sombra real não faz isso: ela é preenchida pela luz que rebate em todo o resto, então mantém um tom. Use no lugar uma versão bem escura do próprio matiz da superfície: um azul-marinho profundo sob uma página cinza fria, um marrom escuro sob um creme. A geometria não muda em nada, e o resultado para de parecer sujeira.
Cores de sombra quase sempre são escritas como rgba(), então você precisa dos valores de canal daquele tom escuro e não do hex com que você desenhou. Um conversor de hex para RGB te leva lá em um passo, e ele também gera os tons se você precisar escurecer uma cor de marca antes. Se o que trava é a notação em si, o que hex, RGB e HSL descrevem cada um é a leitura de base.
Onde as sombras inset são pintadas
Adicione inset a uma camada e ela é desenhada dentro da caixa de padding: em cima do fundo, embaixo do conteúdo e recortada pelo raio dos cantos, então ela acompanha os cantos arredondados sem que você faça nada. É isso que faz um input parecer afundado ou um botão parecer pressionado enquanto está sendo segurado.
Camadas inset e camadas para fora podem viver na mesma lista separada por vírgulas. Elas são independentes e pintadas na ordem, a primeira por cima. As camadas para fora seguem a caixa da borda e as inset a caixa de padding, e as duas são recortadas pelo raio dos cantos, então o raio e a forma da sombra estão amarrados: muda um e a outra se remodela junto, o que vale saber antes de brigar com qualquer um dos dois. Como o border-radius se comporta de verdade cobre a metade que surpreende as pessoas.
box-shadow ou filter: drop-shadow?
box-shadow segue a caixa da borda, sempre. Se o seu elemento é um PNG transparente, um ícone SVG ou uma forma recortada com clip-path, você ainda ganha um retângulo flutuando atrás dele. filter: drop-shadow() segue o canal alfa visível e te dá o contorno que você realmente queria.
A contrapartida: drop-shadow custa mais para renderizar, não aceita nenhum valor de spread —então o truque do spread negativo acima fica indisponível— e se aplica ao elemento e a tudo que está dentro dele, filhos incluídos. Use box-shadow para retângulos e retângulos arredondados, que é a maior parte de uma interface, e drop-shadow quando a silhueta importa.
O que quebra uma sombra que estava boa
- overflow: hidden corta a sombra. Uma sombra não ocupa espaço no layout, então um ancestral que esconde o overflow a corta como qualquer outra coisa que fica para fora. Adicione padding ao pai, ou mova a sombra para um elemento fora da área recortada.
- Uma segunda regra box-shadow substitui a primeira. É uma propriedade só, não uma lista em que você vai acrescentando. Se uma regra posterior define
box-shadow, as suas camadas anteriores somem: coloque todas as camadas na mesma declaração. - Animar o blur ou o spread repinta a cada frame. Isso fica caro rápido em elementos grandes. Coloque a sombra num pseudoelemento e anime a opacidade desse elemento; opacidade é barata, borrar de novo não é.
- Interfaces escuras quase não mostram a sombra. Preto a 14% sobre uma superfície quase preta é quase invisível. Temas escuros normalmente separam superfícies com uma borda clara e fraca, ou deixando a superfície elevada mais clara, em vez de reaproveitar os valores de sombra do modo claro.
Última coisa: teste no fundo que você vai publicar de verdade. Uma sombra ajustada no branco pode sumir sobre uma fotografia ou um gradiente, e esse é o motivo mais comum para um card parecer convincente no arquivo de design e chapado na página no ar.
A versão em camadas é genuinamente chata de escrever na mão, então o gerador de box shadow daqui mantém quatro camadas vivas ao mesmo tempo e atualiza o CSS enquanto você arrasta: troque o fundo do preview para escuro antes de decidir que terminou, porque é ali que a maioria das sombras desmorona. Se o que você ainda está enfrentando é a cor e não a geometria, montar uma paleta de cores que se sustenta explica como derivar o tom escuro que a sua sombra deveria estar usando desde o começo.
Perguntas frequentes
Como o box-shadow funciona no CSS?
O navegador desenha uma cópia da caixa do elemento atrás dela, deslocada pelos offsets horizontal e vertical, redimensionada pelo spread, suavizada pelo blur e preenchida com uma única cor chapada. A forma segue a caixa da borda, incluindo qualquer border-radius. Ela é pintada, não entra no layout, então nunca move os outros elementos.
O que significam os quatro números do box-shadow?
Na ordem: deslocamento horizontal, deslocamento vertical, raio de blur e raio de spread. Os dois últimos são opcionais e valem zero por padrão, e a cor pode ser escrita antes ou depois das medidas. Porcentagens não são permitidas em nenhum deles.
Como faço uma sombra em um lado só?
Dê à sombra um spread negativo perto do valor do blur dela e depois desloque-a para o lado que você quer. Algo como 0 10px 8px -8px impede que a transição escape para a esquerda, para a direita e para cima, então só a borda de baixo mostra sombra.
Por que o meu box-shadow não aparece?
As causas mais comuns são um ancestral com overflow: hidden cortando a sombra, uma regra CSS posterior sobrescrevendo a propriedade box-shadow inteira, ou uma opacidade tão baixa que ela some contra o fundo. Uma porcentagem em uma das medidas também invalida a declaração inteira.
Dá para animar um box-shadow?
Sim, box-shadow é animável, mas mudar o blur ou o spread obriga o navegador a repintar a sombra a cada frame e isso é lento em elementos grandes. A solução habitual é colocar a sombra num pseudoelemento ::after e fazer a transição da opacidade desse elemento entre dois estados.
Última atualização 19 de setembro de 2026