Em tempo de dezenas de libraries e de frameworks front-end é muito fácil sermos levados pelo hype, ou pela facilidade de usar algo pré-pronto. De modo algum quero tirar o mérito de utilizar tecnologias e ferramentas já consolidadas no mercado e comunidade para desenvolvimento rápido de produtos e testes de hipóteses. Particularmente, percebo que acabo deixando de estudar conceitos importantes, ou as bases dessas mesmas ferramentas para saber quando elas são realmente necessárias. É deste pensamento que me surgiu a necessidade de estudar o que é o Shadow DOM mais afundo e entender e porque ele é utilizado na maioria dos os frameworks e libs de expressão global, como Vue.js, Angular, React, Aurelia. Porque esse cara é tão importante pro avanço da Web?

O que é o Shadow DOM?

Minha definição preferida do Shadow DOM é a de que ele consiste em um subconjunto de nós do DOM com escopo próprio. Traduzindo isto em algo tangível isto que dizer que seu HTML, CSS e JS serão isolados do resto dos nós irmãos. Isto soa familiar? Nada mais é do que a implementação nativa do browser de componentes utilizando o que já existe no DOM atual.

 

Na prática

Vamos ver esse conceito na prática. No cenário abaixo temos um box vermelho e um input com bordas pretas:

 

Browser

Se quisessemos fazer um módulo teríamos que utilizar herança no CSS e escopos no Javascript. Porém isso ao longo do tempo se mostra complexo, principalmente do ponto de vista de manutenabilidade deste código. É ai que o Shadow DOM se mostra incrível para gerar escopo. Vamos fazer isto:

Neste arquivo criamos um Shadow DOM e criamos um elemento dentro dele de forma programatica. E o efeito no browser foi o seguinte:

Foi criado um elemento novo chamado ‘shadow-root’ com o input. Agora vejamos as implicações disso. Perceba que o elemento que foi criado internamente, não possui o estilo global, ou seja, o estilo em cascata dele é interpretado de forma apartada sem esforço algum. De quebra nós ganhamos um escopo Javascript isolado, ou seja um componente auto-contido. Isso é demais! Você pode me dizer: “Ahh.. mas o framework x, y, z já faz isso há muito tempo…”, e eu serei obrigado a concordar que no efeito talvez, mas no como ele faz não. O que me encanta é que eu não preciso importar 1kb a mais no meu app para ganhar essa funcionalidade.

 

Indo mais a fundo

Agora você pode adicionar estilos específicos, eventos e deixar o seu componente manipulável pelo escopo de fora (open), ou fechá-lo (closed) como mostrado após o nome “#shadow-root” no inspetor:

Aberto

 

Com o Shadow DOM aberto você pode editá-lo do DOM raiz, adicionar elementos, eventos e etc.

Fechado

 

Com o Shadow DOM fechado o componente fica auto-contido, sendo alterado somente por eventos.

Com html imports podemos importar um css específico para esse DOM e ainda carregá-lo assíncrono:


O arquivo css chamado “meumodulo.css” foi carregado dentro do seu módulo de forma auto-contida. Lindo!

Conclusão

Essa é só a ponta de iceberg chamado Shadow DOM, e sua aplicabilidade é vasta, porém ainda dependemos de polyfills pois praticamente o Chrome é o único que o suporta de forma plena na versão 1.0 como visto aqui, porém o ganho de não precisar de MB’s a mais para ter um app componentizado pode compensar. E você, conhecia o Shadow DOM? Me fez repensar que isto pode evitar builds imensos no front-end para css e javascript quando o objetivo é somente componentizar o app, ou se devo realmente usar algo opinativo como frameworks para fazer algo simples. Com certeza evoluirá e terá cada vez mais suporte então é importante sabermos como funciona e o que se pode fazer. Se você quer saber mais vale a pena estudar utilizando o guia do google que ensina de forma bem simples como implementar e boas práticas a serem utilizadas no Shadow DOM

 

Fabio Damasceno