Menu

::before e ::after no CSS: pseudo-elementos com exemplos

::before e ::after inserem conteúdo gerado como primeiro e último filho de um elemento, direto do CSS. Veja a propriedade content, por que content vazio é obrigatório, como posicioná-los, tooltips com attr(), contadores e onde eles não funcionam.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

O que ::before e ::after fazem

::before insere uma caixa como primeiro filho de um elemento e ::after como último filho. O que vai dentro da caixa é definido pela propriedade content. Nada é acrescentado ao HTML: o navegador gera tudo a partir do CSS.

O HTML contém só 9 e Tests pass. O cifrão, o rótulo "/ month" e o sinal de visto vêm todos do CSS. Eles herdam os estilos do elemento (fonte, cor), a menos que você os sobrescreva, como fazem os exemplos acima.

Sintaxe

selector::before {
  content: "text";   /* required */
  /* any other styles */
}

selector::after {
  content: "";       /* empty string: a box with no text */
}
Valor de contentResultado
"text"Uma string. Use "\A" para uma quebra de linha (com white-space: pre) e "\2192" para um caractere Unicode (→)
""Uma caixa vazia, para formas e decorações
attr(data-label)O valor de um atributo do elemento
counter(step)O valor de um contador CSS
open-quote / close-quoteAspas adequadas ao idioma do elemento
none ou normalNenhum pseudo-elemento (normal é o padrão)

content é obrigatório. Sem ele, ::before e ::after nunca são criados, não importa quantas outras propriedades você defina.

Formas decorativas com content: ""

Com content: "", o pseudo-elemento é uma caixa vazia que você pode dimensionar e colorir. Ele é inline por padrão, e uma caixa inline ignora width e height, então dê a ele display: block, inline-block ou position: absolute:

Posicionar um pseudo-elemento

Para uma decoração que fica por cima ou em volta do elemento, use position: absolute no pseudo-elemento e position: relative no próprio elemento, para que os deslocamentos sejam medidos a partir dele:

Repare na ordem ao combinar com uma pseudo-classe: primeiro vem o estado, depois o pseudo-elemento, .link:hover::after, nunca .link::after:hover.

Ler atributos com attr(): um tooltip

attr() traz o valor de um atributo para o content, então uma única regra pode mostrar um texto diferente em cada elemento:

Um tooltip que só aparece no hover fica invisível para quem usa teclado ou toque. Para qualquer coisa importante, coloque o texto na página, ou mostre também no :focus com tabindex="0" no elemento.

Numerar com contadores

Os contadores CSS com ::before numeram coisas sem você digitar os números:

Acrescente ou remova um passo e os números se atualizam sozinhos.

Onde ::before e ::after não funcionam

Pseudo-elementos são inseridos dentro do elemento, entre as tags dele. Elementos sem esse "dentro" não conseguem exibi-los:

  • <img>, <video>, <iframe> (elementos substituídos)
  • <input>, <select>, <textarea> (controles de formulário) e <br>

Alguns navegadores os desenham em um checkbox ou em uma imagem quebrada, mas isso não é consistente. Coloque o pseudo-elemento em um invólucro: <span class="field"><input></span> e estilize .field::after.

Erros comuns

  • Sem content. O motivo mais comum de nada aparecer. Acrescente content: "".
  • Dimensionar um pseudo-elemento inline. width e height não fazem nada até você definir display: block, inline-block ou position: absolute.
  • Ordem errada com um estado. a:hover::after funciona; a::after:hover não.
  • Posição absoluta sem um pai posicionado. O pseudo-elemento se alinha a algum ancestral distante. Acrescente position: relative ao elemento.
  • Colocar conteúdo real no CSS. O texto em content não pode ser selecionado nem copiado. Deixe a informação no HTML.

Perguntas frequentes

O que o ::before faz no CSS?

Ele cria um pseudo-elemento que é o primeiro filho do elemento selecionado, preenchido com o que a propriedade content disser. O ::after faz o mesmo como último filho. Nenhum dos dois existe no HTML, então são práticos para ícones, rótulos e decorações.

Por que meu ::before ou ::after não aparece?

O motivo mais comum é a falta da propriedade content: sem ela o pseudo-elemento não é gerado. Use content: "" para uma caixa decorativa vazia. Outras causas: um pseudo-elemento inline com largura e altura (dê a ele display: block ou inline-block) ou um elemento como <img> ou <input>, que não comporta pseudo-elementos.

Qual a diferença entre :before e ::before?

Nenhuma no comportamento. ::before, com dois dois-pontos, é a sintaxe atual que marca pseudo-elementos; :before, com um só, é a grafia antiga do CSS2 que os navegadores ainda aceitam para before, after, first-line e first-letter.

Dá para usar ::before em um img ou input?

Não de forma confiável. Pseudo-elementos são inseridos dentro do conteúdo do elemento, e elementos substituídos como <img> e controles de formulário como <input> não têm uma caixa de conteúdo para eles. Envolva o elemento em um <span> ou <div> e coloque o pseudo-elemento no invólucro.

Leitores de tela leem o conteúdo do ::before?

Em geral, sim: o texto em content costuma entrar no nome acessível, mas não pode ser selecionado nem copiado. Deixe a informação real no HTML e use pseudo-elementos para decoração e pequenas pistas visuais.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR