CSS element()

Conheça element(), a função de CSS que renderiza qualquer parte de um site como uma imagem ao vivo!

Ir para o artigo

O CSS Image Values and Replaced Content Module Level 4 introduz a função element(). Essa função foi definida anteriormente no nível 3 e, portanto, o Firefox já tem suporte para ela, desde a sua versão 4 (maio de 2011). Simplificando, essa função renderiza qualquer parte de um site como uma imagem ao vivo (live image)!

Ao ver um elemento DOM renderizado diretamente no navegador, você obtém uma imagem dele. Todas as alterações nesse elemento serão vistas imediatamente, em tempo real, na imagem, incluindo a seleção de texto.

É uma feature muito poderosa, de sintaxe bem simples. Basta referenciar o elemento que se deseja obter uma visualização ao vivo usando seu atributo id. Por exemplo, aqui está um texto e uma imagem em div#css-source. A live image desse elemento pode ser usada como background de div#css-result.

À medida que element() cria uma imagem, é possível usar todas as propriedades CSS normalmente para controlá-la, como background, background-repeat, background-size etc.

Eis um demo funcional da coisa:

See the Pen Basic demo element() by Vincent De Oliveira (@iamvdo) on CodePen.

Lembre-se de que qualquer parte de um site pode ser referenciada, inclusive o site inteiro, se for preciso! Mas tenha cuidado: seu elemento pode ser filho da sua fonte (source), caso em que elementos podem aparecer 2 ou mais vezes. No entanto, o Firefox lida bem com referências recursivas.

element() pode facilmente elevar o design de CSS a outro nível, de maneira. Algumas poucas idéias que vêm à mente:

  • Conteúdo duplicado em efeitos avançados
  • Miniaturas em slides anterior/próximo
  • Zoom em imagens de produtos em e-commerces
  • background animado usando animações CSS ou referenciando video, canvas ou SVG
  • Marca d’água com vários fundos da ideia de Lea Verou
  • Enfim, o limite é a imaginação!

Algumas considerações a respeito:

Reflexo com CSS element()

Todos sabemos que reflexos não são mais uma tendência de web design — olá, web 2.0! –, mas esse efeito é um bom ponto de partida para entender melhor o element().

A demo é composta por uma imagem e sua <figcaption>, ambas dentro de uma tag <figure>. A função element() é usada no background do pseudo-elemento ::after para obter uma visualização ao vivo de <figure> ao invertê-la ao longo do eixo Y e mascará-la usando uma máscara SVG.

Todo o efeito fica dentro de @supports para lidar com aprimoramentos para ficar consonante à filosofia de progressive enhancement:

A demo funciona no Firefox, com fallback para a propriedade antiga e não-padrão -webkit-box-reflect para navegadores baseados em WebKit (sem suporte no IE / Edge).

See the Pen Reflections with element() by Vincent De Oliveira (@iamvdo) on CodePen.

Se já está cansado de ver esse efeito de reflexo, vamos a algo mais interessante.

Efeito 3D de papel dobrado com element()

Em alguns efeitos avançados, às vezes é preciso lidar com conteúdo duplicado, e a única opção razoável aqui (até então) é o JavaScript. É muito fácil lidar com conteúdos estáticos (imagens, textos etc.), mas torna-se realmente complicado com os dinâmicos.

Com CSS element(), as coisas ficam muito mais simples.

See the Pen Fold login form by Vincent De Oliveira (@iamvdo) on CodePen.

Indo além, é possível aplicar o efeito de dobra 3D a qualquer coisa que esteja dentro da página, como um mapa interativo:

See the Pen Fold interactive map by Vincent De Oliveira (@iamvdo) on CodePen.

Background animado com element()

Um efeito interessante também pode ser criar fundos animados. Bem, você pode pensar no antigo fundo animado em GIF, mas element() oferece novas possibilidades, como usar uma tag <video>, <canvas> ou <svg>.

Ao combinar , e conteúdo duplicado, torna-se possível criar esse efeito Muitcho Loko™ de dobra com mais de 30 peças, em que ainda é possível desenhar enquanto a animação acontece!

See the Pen Crazy fold video + live canvas drawing by Vincent De Oliveira (@iamvdo) on CodePen.

backdrop-filter fake

Com o element(), torna-se bastante simples criar uma solução alternativa para backdrop-filter e, assim, aumentar o suporte de navegadores. O que é preciso fazer é definir o background de um elemento para ser a live view do elemento abaixo dele. Simples, certo?

See the Pen Faking backdrop-filter with element() by Vincent De Oliveira (@iamvdo) on CodePen.

Também possível com conteúdo dinâmico:

See the Pen iOS 7 background blur with CSS by Vincent De Oliveira (@iamvdo) on CodePen.

Também vale a pena mencionar que é possível backdrop-filter fake com filtros SVG. Algo como (veja a aba HTML):

See the Pen Faking backdrop-filter using SVG filter by Vincent De Oliveira (@iamvdo) on CodePen.

Como ocultar as referências

Em muitos efeitos, foi preciso criar uma máscara de camada para ocultar partes da página. Isso porque não é possível usar display: none em um elemento que está sendo usado como background. Na verdade, a live image não exibirá mais esse elemento.

Também é possível tentar agrupar o elemento de referência dentro de uma <div> com height: 0 e overflow: hidden. Dessa forma, o elemento ainda está presente na página (e pode ser referenciado como uma visualização ao vivo), mas não está mais visível, portanto, não precisando mais de uma máscara de camada.

O problema é que alguns navegadores degradam o desempenho de elementos invisíveis (animações CSS, imagens GIF não animadas etc.) e não é isso que queremos nesse caso específico.

Então, parece que a técnica da máscara é realmente a melhor, por enquanto. Se você conseguir pensar em alguma outra solução, conta pra gente nos comentários.

Conclusão

Apesar do seu (atual) baixo suporte a navegadores e desempenho de renderização duvidoso, deu para ver que CSS element() é incrível!

Se você conhecer outros exemplos tão legais quanto esses e/ou for criar demos usando element(), coloca nos comentários pra gente dar uma olhadinha e até complementar o artigo com esses novos exemplos.

Usamos cookies para melhorar sua experiência e para ajudar a entender como nosso site é usado. Ao utilizar este site, você aceita o uso de cookies. Consulte nossa política de privacidade para obter mais informações.