Como o box-shadow funciona
box-shadow pinta uma sombra em volta da caixa da borda de um elemento. Ela segue o border-radius, não ocupa espaço no layout e precisa de pelo menos dois valores: quanto deslocar na horizontal e na vertical.
A sintaxe
box-shadow: [inset] <offset-x> <offset-y> [<blur>] [<spread>] [<color>];
| Valor | Significado | Padrão |
|---|---|---|
inset | Desenha a sombra dentro da caixa, como uma área afundada | Por fora |
| offset-x | Positivo move para a direita, negativo para a esquerda | Obrigatório |
| offset-y | Positivo move para baixo, negativo para cima | Obrigatório |
| blur | O quanto a borda é suave; não pode ser negativo | 0 (borda nítida) |
| spread | Aumenta (positivo) ou diminui (negativo) a sombra | 0 |
| color | Qualquer cor; um preto semitransparente costuma ficar melhor | A cor do texto |
A quantidade de comprimentos decide o significado: dois são os deslocamentos, três acrescentam o desfoque, quatro acrescentam o spread. Teste:
Experimente 0 0 0 4px #f59e0b (um anel), inset 0 0 12px #2563eb e -8px -8px 0 #16a34a.
Spread: anéis e sombras de um lado só
O spread muda o tamanho da sombra antes do desfoque. Dois padrões saem disso:
- Um anel: sem deslocamento, sem desfoque, só spread. Ao contrário de uma borda, ele não muda o tamanho do elemento, então é um bom indicador de foco (
:focus-visible { box-shadow: 0 0 0 3px #2563eb; }). - Um anel com vão: empilhe um spread branco embaixo de um colorido maior.
- Um lado só: mova a sombra para baixo e encolha com um spread negativo, para que ela só apareça embaixo.
Sombras em camadas para uma profundidade realista
Sombras reais têm uma parte escura e nítida perto do objeto e uma parte suave e fraca mais longe. Duas ou três camadas imitam isso muito melhor que um único desfoque grande:
A primeira sombra da lista é pintada por cima. Mantenha as cores das sombras em preto semitransparente ou em um tom escuro do fundo, nunca cinza puro, para que escureçam o que estiver embaixo.
Sombras inset
inset desenha a sombra dentro da caixa do padding, como se a superfície estivesse afundada. Combina com campos de texto, áreas rebaixadas e botões pressionados:
input {
box-shadow: inset 0 1px 3px rgb(0 0 0 / 20%);
}
button:active {
box-shadow: inset 0 3px 6px rgb(0 0 0 / 30%);
}
Uma sombra inset é desenhada acima do fundo, mas abaixo do conteúdo. Sombras que seguem o formato das letras em vez da caixa são text-shadow.
Erros comuns
- Sombras pretas puras e totalmente opacas. Parecem um contorno escuro. Use alfa de 10% a 30%.
- Um único desfoque enorme para dar profundidade. Combine uma sombra pequena e nítida com uma grande e suave.
- Uma sombra cortada na borda. Um ancestral com
overflow: hiddena recorta; acrescente padding ao ancestral ou mude a regra de overflow de lugar. - Desfoque negativo. É inválido e a declaração inteira é ignorada.
- Animar
box-shadowem muitos elementos. Isso repinta a cada quadro. Em páginas pesadas, anime aopacityde um pseudo-elemento que carrega a sombra maior.
Perguntas frequentes
Qual é a sintaxe do box-shadow?
box-shadow: offset-x offset-y blur spread color;, por exemplo box-shadow: 0 4px 12px 0 rgb(0 0 0 / 15%);. Só os dois deslocamentos são obrigatórios; acrescente inset para desenhar a sombra dentro da caixa.
O que o spread faz no box-shadow?
Ele aumenta (positivo) ou diminui (negativo) a sombra antes do desfoque. Uma sombra sem deslocamento, sem desfoque e com spread de 3px é um anel sólido de 3px em volta do elemento.
Como colocar sombra só embaixo?
Desloque a sombra para baixo e encolha com um spread negativo para os lados sumirem: box-shadow: 0 8px 6px -6px rgb(0 0 0 / 40%);.
O box-shadow afeta o layout?
Não. A sombra não ocupa espaço nem move outros elementos, e por isso é uma boa forma de criar um anel de foco ou um efeito de elevação no hover sem deslocar o layout. Ela pode ser cortada pelo overflow: hidden de um ancestral.
Dá para ter várias box-shadows?
Sim, separe-as com vírgulas. A primeira sombra é desenhada por cima. Combinar uma sombra pequena e nítida com uma grande e suave fica mais natural que uma única sombra grande.