Animando pseudoelementos

Os pseudoelementos funcionam como se ganhássemos novos elmentos do DOM. Eles nos permitem adicionar em nossas páginas conteúdo extra, decoração, e muito mais, sem adicionar nada ao HTML. E eles podem ser animados. Neste post, nós usaremos um pseudoelemento para adicionar um pouco do estilo visual para um botão.

Pseudoelementos

No CSS, podemos especificar um pseudoelemento usando ::before ou ::after. O pseudoelemento é inserido dentro de um elemento, entre este e qualquer outro conteúdo. Uma vez que ele atua como se fosse um próprio elemento, pode ser estilizado, posicionado, etc. O código é um pouco parecido com este:

.pebble::before {
  ...
}
.pebble::after {
  ...
}

Neste ponto, nosso elemento .pebble tem dois elementos virtuais anexados, e nós podemos estilizá-los conforme necessário.

Nota sobre "::" versus ":"

É geralmente aceito que usemos dois-pontos duplos :: para denotar pseudoelementos (ao contrário das pseudoclasses como :hover, :first-child). Mas se você estiver adicionando suporte ao IE8, é melhor usar um único dois-pontos :. Todos os outros navegadores e versões mais recentes do IE suportam os dois-pontos duplos.

Não se esqueça do "conteúdo"

Ao adicionar pseudoelementos, uma coisa a manter em mente é a necessidade de especificar a propriedade content para que eles possam ser visíveis na página. Como o pseudoelemento é criado sem conteúdo, nós podemos criar um truque para fazê-lo aparecer usando um content vazio, desse jeito:

.pebble::before {
  content: ""
  ... more styling goes here...
}

Isto deve gaantir que o elemento seja visível na tela.

Exemplo: Botão brilhante

Para este exemplo, usaremos um pseudoelemento para criar um efeito brilhante ao passar o mouse sobre um botão. Aqui está um exemplo em ação (Passe o mouse ou toque para ver o efeito).

Para começar, um pouco de HTML:

<button>Oooh SHINY</button>

Já que estamos usando pseudoelementos, não precisaremos de mais HTML do que isso para começar. Você pode querer adicionar uma classe para o botão se quiser diferentes estilos numa mesma página, mas, por enquanto, vamos usar o elemento genérico por simplicidade.

Adicionando o efeito de brilho

O efeito de brilho é um gradiente linear que passa através do botão. Para criar isto, nós usaremos o pseudoelemento after e vamos posicioná-lo inicialmente do lado de fora do botão:

button::after {
  content: '';
  position: absolute;
  top: -50%;
  right: -50%;
  bottom: -50%;
  left: -50%;
  background: linear-gradient(to bottom, rgba(229, 172, 142, 0), rgba(255,255,255,0.5) 50%, rgba(229, 172, 142, 0));
  transform: rotateZ(60deg) translate(-5em, 7.5em);
}

O efeito de brilho é composto por um gradiente da cor do botão para branco, numa direção, e o inverso na volta. Neste momento, ele está aparecendo do lado de fora o botão.

Nós precisamos ocultar a camada de brilho, para que ela só apareça ao passarmos o mouse. Para fazer isso nós definiremos a propriedade overflow do botão para hidden. Como o pseudoelemento está dentro do botão, isto significa que seu posicionamento do lado de fora o botão não será visível.

button {
  background: #e5ac8e;
  color: #fff;
  font-size: 14px;
  border-radius: 0.5em;
  padding: 0 1em;
  position: relative;
  overflow: hidden;
  line-height: 32px;
}

Eu adicionei outros estilos também para dar ao botão uma cara própria. Uma coisa a salientar é o uso de position: relative. Adicionei essa propriedade para que o pseudoelemento posicionado absolutamente fique dentro do botão. Sem especificar a posição, um item absolutamente posicionado irá se basear na posição do elemento pai (geralmente, o body).

Adicionando a animação

Uma vez que estaremos usando uma animação neste exemplo, há duas etapas envolvidas. A primeira é dizer ao browser para usar uma animação no evento do passar do mouse. Em seguida, nós definiremos exatamente o que é a animação, usando keyframes (quadros-chave).

Adicionar o estado "hover" pode ser feito empilhando o after sobre o hover, desta forma:

button:hover::after, button:focus::after {
  animation: sheen 1s forwards;
}

Aqui estamos dizendo ao navegador que ao passar do mouse, o pseudoelemento after deve ganhar uma anima&ccedil;&atilde;o. A animação, chamada brilho, dura um segundo e para ao final sem se repetir.

A ordem é importante aqui. Usar ::after:hover não funcionará, pois estaremos dizendo ao navegador para reagir ao estado "hover" do próprio pseudoelemento.

Também adicionei o estado de foco. Isto significa que os usuários usando a tecla tab para navegar na página vão ver o efeito de brilho, sem a necessidade de passarem o mouse. (Obrigado, Šime Vidas, pela dica)

Vamos especificar keyframes para esta animação:

@keyframes sheen {
  100% {
    transform: rotateZ(60deg) translate(1em, -9em);
  }
}

Só precisamos de um quadro-chave neste caso. Como a posição inicial (0%) está implícita pela posição inicial do pseudoelemento, apenas precisamos descrever a posição final. Neste caso, a posição final é do outro lado, no canto superior direito do botão. O navegador então animará o efeito de brilho em toda a extensão.

Considerações sobre navegadores

A propriedade de animação é bem suportada, como são os pseudoelementos. É sempre bom, para ter certeza, incluir prefixos -webkit e -moz para os keyframes e quaisquer transformações.