Crie Web Components Reutilizáveis Sem Frameworks (Vanilla JS)

Os Web Components são uma maneira poderosa e moderna de criar elementos personalizados na web. Por exemplo, você pode criar um componente para um menu de navegação que pode ser reutilizado em diferentes páginas de um site, encapsulando tanto o estilo quanto o comportamento do menu de forma independente. Eles permitem encapsular funcionalidades e estilos em um componente reutilizável, otimizando o desenvolvimento de aplicações web. Neste guia, abordaremos como criar um Web Component que carrega um arquivo HTML externo e o insere no DOM, tornando-o uma parte integral da página.
O Que São Web Components?
Imagine os Web Components como blocos de LEGO. Cada componente é independente, com sua própria aparência e comportamento, mas pode ser reutilizado em diferentes contextos sem interferir no restante do código.
Os Web Components utilizam HTML, CSS e JavaScript para criar elementos encapsulados que funcionam como blocos modulares. Eles são amplamente compatíveis com frameworks como React, Angular e Vue, oferecendo grande flexibilidade.
Estrutura do Projeto
Aqui está a estrutura de um projeto simples que utiliza Web Components, acompanhada de uma breve explicação sobre o propósito de cada pasta e arquivo listado:
webComponents/
├── components/ # Arquivos HTML reutilizáveis
│ ├── body.html # Corpo da página
│ ├── menu.html # Menu de navegação
│ └── footer.html # Rodapé
├── css/ # Arquivos de estilo
│ └── styles.css # Estilos globais
├── js/ # Scripts JavaScript
│ └── script.js # Gerenciamento dos Web Components
├── index.html # Página principal
└── readme.md # Instruções do projeto
Como Funciona a Estrutura
- Componentes HTML: Localizados na pasta
components/, são carregados dinamicamente pelo JavaScript. - Estilos: O arquivo
styles.cssaplica estilizações globais e específicas. - Scripts: O arquivo
script.jsdefine e gerencia os Web Components.
Introdução ao Passo a Passo
Neste passo a passo, você aprenderá como criar um Web Component desde sua definição até sua integração em um projeto. Este guia é ideal para iniciantes e também para desenvolvedores que desejam aprofundar seus conhecimentos na criação de elementos personalizados reutilizáveis. Ao final, você terá os fundamentos para criar componentes reutilizáveis que podem ser aplicados em projetos reais.
Passo a Passo para Criar um Web Component
1. Criar a Classe Base
class BaseComponent extends HTMLElement {
constructor(templatePath) {
super();
this.templatePath = templatePath;
}
async connectedCallback() {
const templateResponse = await fetch(this.templatePath);
const templateHTML = await templateResponse.text();
this.innerHTML = templateHTML;
}
}
- Classe Base: Herda de
HTMLElement. - Constructor: Recebe o caminho do arquivo HTML.
- connectedCallback: Executa ao adicionar o componente ao DOM, carregando o arquivo HTML correspondente.
Sobre o uso de innerHTML aqui: como o conteúdo vem de arquivos .html do próprio projeto (não de entrada do usuário), o risco de XSS é baixo. Se um dia esses templates vierem de uma fonte externa ou editável por terceiros, prefira sanitizar o HTML antes de atribuí-lo, ou usar <template> + content.cloneNode(true).
2. Definir Componentes Personalizados
function defineComponent(tagName, templatePath) {
customElements.define(tagName, class extends BaseComponent {
constructor() {
super(templatePath);
}
});
}
defineComponent('menu-component', 'components/menu.html');
defineComponent('body-component', 'components/body.html');
defineComponent('footer-component', 'components/footer.html');
- Função Auxiliar: Simplifica a definição de novos componentes.
- Componentes Definidos:
menu-component,body-componentefooter-componentcarregam os arquivos correspondentes.
Atenção às aspas: ao escrever essas três últimas linhas, use o mesmo tipo de aspas para abrir e fechar cada string ('menu-component', não 'menu-component"). Misturar aspas simples e duplas na mesma string é um erro de sintaxe comum ao copiar código de fontes diferentes, e o navegador vai rejeitar o script inteiro com um SyntaxError — sem executar nada, o que pode ser confuso para quem está começando, já que a página simplesmente fica em branco sem nenhum componente renderizado.
Por que customElements.define exige um hífen no nome? A especificação de Web Components exige que todo nome de elemento personalizado contenha um hífen (menu-component, e não menucomponent). Isso evita colisão com nomes de tags HTML nativas atuais e futuras.
3. Integrar os Componentes no HTML
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Usando Web Components</title>
<link rel="stylesheet" href="/css/styles.css">
</head>
<body>
<menu-component></menu-component>
<body-component></body-component>
<footer-component></footer-component>
<script src="/js/script.js"></script>
</body>
</html>
- Estrutura Modular: Os componentes são inseridos diretamente na página principal, facilitando a organização do código.
Componentes HTML Exemplo
Arquivo menu.html
<header>
<h3>Site Criado com Web Components</h3>
<nav>
<ul>
<li><a href="#home">Home</a></li>
<li><a href="#services">Serviços</a></li>
<li><a href="#about">Sobre</a></li>
<li><a href="#contact">Contato</a></li>
</ul>
</nav>
</header>
- Semântica: Usa tags como
<header>e<nav>para melhorar a acessibilidade e o SEO. - Links: Permitem a navegação dentro da página.
Arquivo body.html
<main>
<section id="section1">
<h2>Seção 1</h2>
<p>Conteúdo da seção 1.</p>
</section>
<section id="section2">
<h2>Seção 2</h2>
<p>Conteúdo da seção 2.</p>
</section>
</main>
<aside>
<h3>Barra Lateral</h3>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</aside>
- Estrutura: Divide o conteúdo principal em seções e inclui uma barra lateral.
Arquivo footer.html
<footer>
<ul>
<li><a href="#home">Home</a></li>
<li><a href="#services">Serviços</a></li>
<li><a href="#about">Sobre</a></li>
<li><a href="#contact">Contato</a></li>
</ul>
<div class="footer-bottom">
<p>© 2025 - Todos os direitos reservados</p>
<p>Desenvolvido por: <a href="#">msdicas</a></p>
</div>
</footer>
- Links: Fornece navegação rápida pelo site.
- Informações Adicionais: Inclui detalhes de direitos autorais e um link para o desenvolvedor.
Estilização com CSS
O arquivo styles.css contém estilos básicos para melhorar a aparência dos componentes. Aqui está uma visão geral:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
line-height: 1.6;
}
header {
margin-bottom: 1.5rem;
background-color: #333;
color: white;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding: 1rem 6rem;
position: fixed;
}
h3 {
font-size: 1.5rem;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
gap: 2rem;
}
nav ul li a {
color: white;
text-decoration: none;
font-size: 1rem;
transition: color 0.3s ease;
}
nav ul li a:hover {
color: #ffd700;
}
footer {
background-color: #333;
color: white;
padding: 20px 0;
text-align: center;
}
.footer-bottom {
border-top: 1px solid #555;
padding-top: 15px;
}
- Estilos Globais: O reset CSS é aplicado para consistência em diferentes navegadores.
- Menu e Rodapé: Estilos específicos melhoram a apresentação do cabeçalho e rodapé, como o uso de cores e alinhamento responsivo.
Repare que corrigimos align-content: center para align-items: center no seletor header: como o header tem um único eixo de itens em linha (não múltiplas linhas quebradas), align-content não tem efeito nenhum em um flex container de uma linha só — a propriedade correta para centralizar verticalmente os itens nesse caso é align-items.
Um Ponto de Atenção: position: fixed no Cabeçalho
O CSS acima usa position: fixed no header, o que o mantém sempre visível no topo da tela ao rolar a página — útil para navegação, mas com um efeito colateral comum: elementos fixos são removidos do fluxo normal do documento, então o conteúdo abaixo (body-component) pode ficar parcialmente coberto pelo cabeçalho. Para evitar isso, adicione um padding-top ao <body> equivalente à altura do cabeçalho:
body {
padding-top: 80px; /* ajuste conforme a altura real do seu header */
}
Benefícios do Uso de Web Components
- Reutilização: Facilita a criação de elementos reutilizáveis.
- Encapsulamento: Evita conflitos de estilos e scripts.
- Flexibilidade: Pode ser usado com qualquer framework ou biblioteca.
Limitações Desta Implementação
Vale ter em mente que esta versão simplificada não usa Shadow DOM, o recurso da especificação de Web Components que isola de verdade o CSS e o JavaScript do componente do restante da página. Sem Shadow DOM, os estilos de styles.css continuam sendo globais — um seletor h3 no CSS afeta qualquer <h3> da página, não só o do menu-component. Para encapsulamento real, o próximo passo natural é anexar o template a this.attachShadow({ mode: 'open' }) dentro de connectedCallback, em vez de atribuir diretamente a this.innerHTML.
Conclusão
Os Web Components permitem criar aplicações modulares, eficientes e fáceis de manter. Ao seguir este guia, você está pronto para explorar o desenvolvimento de componentes personalizados e reaproveitáveis, aproveitando o melhor da tecnologia web moderna. Para ir além, vale estudar Shadow DOM e o elemento <template>. Consulte a documentação da MDN para mais detalhes.
Confira nossos projetos no GitHub e colabore com a comunidade!
Comentários
Não foi possível carregar os comentários no momento.
Deixe seu comentário