# CSS box-shadow: sombras suaves e em camadas que parecem reais

[Canonical HTML page](https://gradiently.design/pt-pt/guide/css-box-shadow)

Uma única box-shadow cinzenta é a forma mais rápida de fazer uma interface parecer um modelo pronto. As sombras reais são várias sombras ao mesmo tempo, com cor, e mais discretas do que pensas.

## The short version

- A propriedade CSS box-shadow aceita uma palavra-chave inset opcional, dois deslocamentos, um raio de desfoque, um raio de expansão e uma cor.
- Uma só box-shadow parece artificial porque os objetos reais projetam ao mesmo tempo uma sombra de contacto nítida e uma sombra larga e suave.
- Empilhar três a cinco sombras, cada uma com cerca do dobro do deslocamento e do desfoque da anterior e com baixa opacidade, produz uma sombra suave e credível.
- Dar à sombra o tom do fundo parece mais natural do que o preto puro em superfícies coloridas ou quentes.
- Animar a box-shadow repinta a cada fotograma, por isso faz antes surgir a opacidade de um pseudo-elemento que leve a sombra maior.

Uma **box-shadow em CSS** escreve-se `box-shadow: 0 4px 12px rgb(0 0 0 / 0.15)`: um deslocamento horizontal, um vertical, um raio de desfoque, uma expansão opcional e uma cor. Essa única sombra serve para um protótipo rápido, mas raramente parece real. As sombras que convencem o olho são em camadas: várias sombras num só elemento, cada uma maior e mais ténue do que a anterior, com o tom da superfície por baixo.

## Sintaxe da box-shadow

```css
/* inset? | offset-x | offset-y | blur | spread | color */
.card { box-shadow: 0 4px 12px 0 rgb(0 0 0 / 0.15); }

/* Negative spread tucks the shadow under the box */
.card { box-shadow: 0 12px 24px -8px rgb(0 0 0 / 0.25); }

/* Inset: a shadow inside the box, like a pressed well */
.well { box-shadow: inset 0 2px 4px rgb(0 0 0 / 0.12); }

/* Spread only: a hairline that follows border-radius */
.chip { box-shadow: 0 0 0 1px rgb(15 23 42 / 0.08); }

/* Several shadows, comma separated, first on top */
.card { box-shadow: 0 1px 2px rgb(0 0 0 / 0.1), 0 8px 16px rgb(0 0 0 / 0.08); }
```

A sombra segue sempre o `border-radius`, e por isso uma sombra só de expansão faz uma linha fina arredondada sem alterar a composição.

| Valor | Predefinição | Efeito |
| --- | --- | --- |
| `inset` | Desligado | Desenha a sombra dentro da borda em vez de fora |
| Deslocamento x e y | Obrigatório | Move a sombra. Luz de cima significa um y positivo |
| Desfoque | 0 | Suaviza a margem. Valores maiores alargam o desvanecimento |
| Expansão | 0 | Aumenta ou reduz a sombra antes de desfocar. Negativa recolhe-a |
| Cor | `currentcolor` | Usa uma cor com alfa; sombras opacas parecem autocolantes |

A expansão é o valor que a maioria ignora e o que mais corrige. Uma pequena expansão negativa impede que um desfoque grande vaze pelas laterais.

## Porque é que uma só sombra parece falsa

Põe um livro numa mesa e olha para a sombra. Mesmo na margem onde toca, a sombra é escura e nítida. Mais longe torna-se larga e ténue, porque a luz envolve o objeto vinda de muitas direções. Uma só `box-shadow` só pode ser uma dessas coisas de cada vez: estreita e dura, ou larga e desfocada. De qualquer forma, o olho nota que falta algo.

### Sombra única

- Um desfoque médio em preto a 25 por cento
- Um halo cinzento à volta de todo o cartão
- Difícil perceber a que altura o cartão flutua
- Parece suja em fundos coloridos

### Sombra em camadas

- Quatro sombras, cada uma mais ténue e mais larga
- Densa junto à margem, arejada ao longe
- A altura lê-se de relance
- Com o tom certo para assentar de forma natural na superfície

## Como empilhar box-shadows

O método é simples: começa pequeno e nítido e depois duplica o deslocamento e o desfoque a cada camada extra, mantendo todas as camadas ténues. As opacidades somam-se onde as camadas se sobrepõem, por isso os valores individuais podem ser surpreendentemente baixos.

1. **Começa com uma sombra de contacto** `0 1px 1px` com cerca de 8 por cento de opacidade. É a linha escura mesmo debaixo da margem.
2. **Duplica a cada camada** Depois `0 2px 2px`, `0 4px 4px`, `0 8px 8px`. O deslocamento e o desfoque crescem juntos, por isso a luz parece vir de cima.
3. **Mantém cada camada ténue** Entre 5 e 10 por cento cada. Se o resultado parecer pesado, remove a camada maior antes de escurecer o que quer que seja.
4. **Dá tom à cor** Troca o preto por uma versão profunda do tom do fundo, como um azul-marinho em páginas azuis ou um castanho em creme.

```css
:root {
  /* Shadow colour as channels, so opacity can vary per layer */
  --shadow-color: 222 47% 11%;

  --shadow-sm:
    0 1px 1px hsl(var(--shadow-color) / 0.08),
    0 2px 2px hsl(var(--shadow-color) / 0.06);

  --shadow-md:
    0 1px 1px hsl(var(--shadow-color) / 0.08),
    0 2px 2px hsl(var(--shadow-color) / 0.07),
    0 4px 4px hsl(var(--shadow-color) / 0.06),
    0 8px 8px hsl(var(--shadow-color) / 0.05);

  --shadow-lg:
    0 1px 1px hsl(var(--shadow-color) / 0.07),
    0 2px 2px hsl(var(--shadow-color) / 0.07),
    0 4px 4px hsl(var(--shadow-color) / 0.06),
    0 8px 8px hsl(var(--shadow-color) / 0.06),
    0 16px 16px hsl(var(--shadow-color) / 0.05),
    0 32px 32px hsl(var(--shadow-color) / 0.04);
}

.card { box-shadow: var(--shadow-md); }
.dialog { box-shadow: var(--shadow-lg); }
```

Uma escala de elevação de três passos como propriedades personalizadas. Muda `--shadow-color` uma vez e todas as sombras do sistema acompanham.

Guardar sombras como variáveis transforma-as em tokens de design, o que mantém coerentes todos os cartões, menus e diálogos. As [variáveis CSS para temas](https://gradiently.design/pt-pt/guide/css-custom-properties-theming) e os [tokens de design](https://gradiently.design/pt-pt/guide/design-tokens) mostram como as ligar a um tema completo.

## Uma escala de elevação para uma interface

A sombra é um sinal de altura, por isso deve significar o mesmo em todo o lado. Escolhe três ou quatro níveis e atribui-os a funções. O que flutua mais alto recebe uma sombra maior e mais suave, nunca só mais escura.

| Nível | Token | Usa para |
| --- | --- | --- |
| 0 | none, ou uma linha fina de expansão de 1px | Campos, linhas de tabela, cartões planos numa página com tom |
| 1 | `--shadow-sm` | Cartões em repouso, botões que devem parecer premíveis |
| 2 | `--shadow-md` | Cartões com o rato por cima, menus pendentes, popovers |
| 3 | `--shadow-lg` | Diálogos, painéis, tudo o que fica sobre uma página escurecida |

Quatro níveis cobrem quase todas as interfaces. Mais do que isso e as pessoas deixam de os distinguir.

## Sombras em fundos coloridos e escuros

As sombras de preto puro ficam cinzentas e lamacentas numa superfície colorida, tal como o preto misturado em tinta a embacia. Tira antes a cor da sombra do fundo: uma sombra azul-petróleo profundo numa página de menta, um ameixa escuro numa de lilás. Em fundos de gradiente, escolhe a paragem mais escura do gradiente e usa-a com baixa opacidade.

- Página menta: #f0fdfa
- Sombra azul-petróleo: #134e4a
- Página lilás: #faf5ff
- Sombra ameixa: #3b0764
- Página creme: #fdf6ec
- Sombra castanho-escuro: #451a03

Três cores de página, cada uma com a cor de sombra que lhe assenta. Usa os tons de sombra a 5 a 10 por cento por camada.

No modo escuro, as sombras quase desaparecem, porque há pouca luz para bloquear. Mostra a altura tornando as superfícies elevadas ligeiramente mais claras e mantém uma linha fina ténue na margem. O [design para modo escuro](https://gradiently.design/pt-pt/guide/dark-mode-design) percorre as cores das superfícies. Para painéis que flutuam sobre imagens, um [backdrop filter](https://gradiently.design/pt-pt/guide/css-blur-background) separa muitas vezes as camadas melhor do que uma sombra mais pesada.

## Animar a box-shadow sem engasgos

Alterar a `box-shadow` ao passar o rato obriga o navegador a repintar a sombra em cada fotograma da transição. Num botão não há problema. Numa grelha de cinquenta cartões, engasga. A solução habitual é pôr a sombra maior num pseudo-elemento e fazer surgir a sua opacidade, o que o navegador consegue compor com pouco custo.

```css
.card {
  position: relative;
  box-shadow: var(--shadow-sm);
}

.card::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: var(--shadow-lg);
  opacity: 0;
  transition: opacity 200ms ease-out;
  pointer-events: none;
}

.card:hover::after { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .card::after { transition: none; }
}
```

Ambas as sombras são pintadas uma só vez. Ao passar o rato só muda a opacidade, por isso nada é repintado durante a transição.

Há mais sobre o que custa tempo de pintura no [desempenho dos gradientes em CSS](https://gradiently.design/pt-pt/guide/css-gradient-performance), e a mesma abordagem em camadas serve para botões nos [botões com gradiente em CSS](https://gradiently.design/pt-pt/guide/css-gradient-button).

## Quando dispensar a sombra

As sombras separam uma superfície do que está por trás. Se o fundo é um gradiente rico ou uma fotografia, uma sombra forte luta com ele. Muitas vezes um fundo mais calmo faz mais pelo cartão do que qualquer sombra. Os Marks do Gradiently são feitos para isso: cada um é um fundo vivo com as suas cores, luz e grão, e as palavras que lá pões continuam legíveis porque o Mark se acalma por trás delas, sem caixas nem sombras a fazer o trabalho.

## FAQ

### Quais são os valores da box-shadow em CSS?

Um `inset` opcional, um deslocamento horizontal, um vertical, um raio de desfoque, um raio de expansão e uma cor, por exemplo `0 4px 12px 0 rgb(0 0 0 / 0.15)`.

### Como faço uma sombra suave em CSS?

Empilha três a cinco sombras, duplicando o deslocamento e o desfoque de cada vez, com 5 a 10 por cento de opacidade cada. Dá-lhes o tom da cor do fundo.

### Como acrescento mais do que uma box-shadow?

Separa-as com vírgulas numa só declaração `box-shadow`. A primeira sombra listada é desenhada por cima.

### O que faz a expansão na box-shadow?

Aumenta ou reduz a sombra antes de ser desfocada. Uma expansão negativa impede que um desfoque grande se veja nas laterais da caixa.

### Animar a box-shadow é mau para o desempenho?

Repinta a cada fotograma. Põe antes a sombra do rato por cima num pseudo-elemento e faz a transição da sua opacidade.
