O que o opacity faz
opacity define o quanto um elemento é transparente: 1 é sólido (o padrão), 0 é invisível, e qualquer valor no meio deixa o fundo aparecer. As caixas abaixo ficam sobre um fundo listrado para você enxergar isso:
A última caixa continua ali: ela ocupa o espaço de 90px na linha, só não desenha nada. Repare que os números brancos esmaecem junto com as caixas. O opacity vale para o elemento e tudo o que está dentro dele.
Fundo transparente, texto sólido
Como a opacidade esmaece os filhos também, ela é a ferramenta errada para "um fundo transparente atrás de um texto legível". Use uma cor de fundo com canal alfa:
Os dois painéis brancos deixam as listras aparecerem na mesma medida. No primeiro, o texto esmaece junto com o painel. No segundo, só a cor de fundo é transparente (rgb(255 255 255 / 0.6), o mesmo que rgba(255, 255, 255, 0.6)), então o texto continua sólido e fácil de ler. As cores com alfa estão na página de cores.
Um filho não escapa da opacidade do pai: opacity: 1 no filho não faz nada, porque o pai é desenhado como uma única camada esmaecida com o filho já dentro.
Valores
| Valor | Resultado |
|---|---|
1 ou 100% | totalmente opaco (padrão) |
0.5 ou 50% | metade transparente |
0 ou 0% | totalmente transparente, ainda no layout e clicável |
1.5, -1 | limitados a 1 e 0 |
A opacidade é herdada visualmente, mas não como propriedade: o opacity calculado de um filho continua 1, enquanto ele é desenhado dentro de um pai esmaecido.
opacity: 0 vs visibility: hidden vs display: none
Os três fazem um elemento sumir, mas diferem em todo o resto:
opacity: 0 | visibility: hidden | display: none | |
|---|---|---|---|
| Ocupa espaço | sim | sim | não |
| Recebe cliques e foco | sim | não | não |
| Lido por leitores de tela | sim | não | não |
| Pode ter transition | sim, suave | troca em uma das pontas, sem fade | não |
A diferença que pega é a segunda linha. Um botão com opacity: 0 ainda pode ser clicado e alcançado pelo Tab:
O painel pergunta ao navegador qual elemento está embaixo de um ponto dentro de cada botão escondido. O botão com opacity: 0 responde "clicável"; o com visibility: hidden, não. O botão Visible começa depois de dois espaços vazios de 150px, porque o botão com display: none é o único que devolveu o espaço. Para fazer algo sumir aos poucos e depois tirá-lo, anime o opacity e defina visibility: hidden no final.
Fade no hover
O opacity é uma das propriedades mais baratas de animar, então é o jeito padrão de fazer coisas aparecerem e sumirem aos poucos. Uma legenda que aparece sobre uma imagem:
O :focus-within mostra a legenda para quem usa teclado também. Lembre da tabela acima: enquanto está invisível, a legenda continua sendo lida pelos leitores de tela, que é o que você quer para uma legenda.
Acessibilidade: texto esmaecido perde contraste
Baixar a opacidade baixa o contraste. Um texto cinza sobre branco com opacity: 0.5 pode cair bem abaixo da razão de 4.5:1 que o texto do corpo precisa. Para texto secundário, escolha uma cor que passe no contraste em vez de esmaecer uma cor escura. Em controles desabilitados, a opacidade reduzida é um sinal comum, mas junte-a ao atributo disabled para que o controle também fique inalcançável pelo teclado e seja anunciado como desabilitado.
Efeito colateral: stacking context
Qualquer opacity abaixo de 1 cria um novo stacking context, como o transform. Os filhos com z-index alto passam a se empilhar só dentro do elemento esmaecido e não conseguem subir acima de elementos de fora. Se um dropdown dentro de um painel esmaecido desliza para baixo de outro elemento, é por isso (a página do z-index explica o empilhamento).
Erros comuns
- Esmaecer um card para deixar o fundo transparente. O texto esmaece junto. Use
rgb(... / 0.5)no fundo. - Tentar deixar um filho opaco de novo. A opacidade do pai limita todos os filhos.
- Esconder só com
opacity: 0. O elemento continua recebendo cliques e foco. Acrescentevisibility: hiddenou usedisplay: none(pointer-events: nonebloqueia cliques, mas não o foco do teclado). - Escrever
opacity: 50. A opacidade vai de 0 a 1;50é limitado a1. Escreva0.5ou50%. - Texto com pouco contraste por causa da opacidade. Confira o contraste do resultado, não da cor original.
Perguntas frequentes
O que o opacity faz no CSS?
Define o quanto um elemento é transparente, de 0 (totalmente transparente) a 1 (totalmente opaco). Vale para o elemento inteiro, incluindo texto, borda, imagens e todos os filhos, como uma única camada achatada.
Como deixar só o fundo transparente, e não o texto?
Não mexa no opacity e dê ao fundo uma cor com alfa: background-color: rgb(37 99 235 / 0.5); ou rgba(37, 99, 235, 0.5). O texto e os filhos continuam totalmente opacos.
Um filho pode ser mais opaco que o pai?
Não. A opacidade do pai vale para o grupo inteiro, então opacity: 1 em um filho não a desfaz. Um filho de um pai com 0.5 é desenhado no máximo com metade da opacidade. Passe a transparência para a cor de fundo do pai.
Qual a diferença entre opacity: 0, visibility: hidden e display: none?
opacity: 0 esconde o elemento, mas ele continua ocupando espaço, pode ser clicado e é lido pelos leitores de tela. visibility: hidden mantém o espaço, mas não é clicável nem lido. display: none o tira do layout por completo.
O opacity pode ser uma porcentagem?
Sim. opacity: 50% é o mesmo que opacity: 0.5 em todos os navegadores atuais. Valores abaixo de 0 ou acima de 1 são limitados a essa faixa.