WebComponents es el nombre por el que se conoce a un conjunto de características relacionadas con HTML, CSS y Javascript, mediante las cuales se pueden crear elementos mantenibles, reutilizables y encapsulados llamados componentes, sin que sea necesario utilizar herramientas externas, librerías o frameworks.
Nota: En contexto web, cuando hablamos de un componente nos referimos a una forma de unir el marcado (HTML), estilo (CSS) y funcionalidad (Javascript) con una determinada finalidad.
Los WebComponents persiguen varios objetivos, entre los que se encuentran los siguientes:
Ser fáciles de reutilizar: A menudo, creamos elementos o partes que se repiten en nuestra web. Los WebComponents nos permiten reutilizar ciertas partes e incluirlas mediante una etiqueta HTML personalizada. Una forma cómoda y sencilla de reutilizar elementos web.
Encapsulación: Necesitamos una forma de crear elementos aislados de otros. Por varias razones. Evitar cambiar su contenido por error, evitar colisiones de CSS de elementos que se llaman igual, etc. Se trata de traer una característica muy popular y deseada en el mundo de la programación, que facilita la labor de los desarrolladores y hace más fácil la reutilización en aplicaciones muy grandes.
Interoperabilidad: Facilitar la posibilidad de intercambiar información entre sistemas diferentes, utilizando tecnologías abiertas y estándares, que aseguran que van a funcionar en diferentes dispositivos y con las que no dependemos de tecnologías de empresas particulares y sus decisiones de negocio privadas.
Ser fáciles de mantener: A medida que escribimos código en una web, la cantidad de líneas de código se hace mayor y cada vez es más complicado con un enfoque global. Necesitamos una forma de poder enfocarnos en una característica concreta, que sólo tenga HTML, CSS y Javascript que influya a dicha característica específica.
Por estas (y muchas otras razones) es muy interesante conocer y saber utilizar los WebComponents.
Como hemos dicho anteriormente, los WebComponents son un conjunto de características nativas que hacen posible la creación de componentes webs sin necesitar librerías o frameworks particulares, sino haciendo uso únicamente de HTML, CSS y Javascript. Veamos de que características estamos hablando:
Los custom elements (elementos personalizados) son una de las características principales que forman los WebComponents. Con ellos, se nos permite crear nuestras propias etiquetas HTML, pudiendo dotarlas de su propia funcionalidad, marcado HTML o estilo CSS.
<!-- Card con etiquetas HTML normales -->
<div class="card">
<img src="manzdev.png" alt="ManzDev">
<h1>ManzDev</h1>
<p>ManzDev es un streamer de código.</p>
</div>
En este primer ejemplo, se puede ver el marcado HTML completo de una card de usuario. Sin embargo, en el ejemplo que muestro a continuación, utilizamos una etiqueta personalizada llamada <user-card>
:
<!-- Card utilizando un custom element -->
<user-card name="ManzDev"></user-card>
Al crear un WebComponent le indicamos al navegador que al leer esa etiqueta, debe interpretar en su lugar el código anterior. De esta forma, cada vez que escribamos <user-card>
sería como escribir todo el código anterior, mostrándolo visualmente.
La forma rápida de diferenciar etiquetas personalizadas de las etiquetas nativas de HTML es observando que las primeras deben incluir en su nombre al menos un guión. Toda etiqueta HTML que tenga un guión en su nombre, es una etiqueta personalizada. La funcionalidad de dicho Custom Element se implementará desde Javascript, extendiendo de la clase
HTMLElement
como veremos más adelante.
Otra característica interesante de WebComponents son los templates (plantillas). Se trata de una etiqueta nativa de HTML que nos permite crear contenido inerte en una página, esto es, contenido HTML que no se procesará por el navegador, y que permanecerá «muerto» hasta que lo clonemos mediante Javascript, y creemos nuevos elementos a partir de él.
<template id="user-template">
<div class="user">
<h1>Username</h1>
<img src="user-image.png" alt="Username">
<a href="https://website.com/">URL</a>
</div>
</template>
Todos los elementos que existen en el interior de la plantilla (imágenes, scripts, etc...) no serán procesados durante la carga de la página, por lo tanto, el navegador no invertirá recursos en su procesamiento. Esto nos puede interesar para preparar contenido reutilizable y que solo consuma recursos cuando lo clonemos desde Javascript.
Probablemente, una de las características más interesantes (y complejas) de WebComponents sea el Shadow DOM. Esta característica opcional se basa en crear un DOM (estructura de elementos HTML) particular en un elemento HTML. De esta forma, además del DOM global del documento que normalmente utilizamos, tenemos uno particular.
Así pues, un elemento HTML con Shadow DOM se podría ver de esta forma:
<div class="element">
#shadow-root
<div class="inner-element">
...
</div>
</div>
En el ejemplo anterior, el elemento <div class="element">
forma parte del DOM global del documento. Es un elemento vacío, sólo que en este ejemplo contiene un #shadow-root
, que es el DOM particular (Shadow DOM). En el interior de ese DOM particular del elemento, existe una etiqueta <div class="inner-element">
. Dicha etiqueta HTML forma parte del Shadow DOM del elemento <div class="element">
.
Nota: Aunque sirve para muchas cosas más, la misión del Shadow DOM es crear una estructura aislada. Es una excelente forma de crear estructuras con estilos CSS locales, que sólo repercutan en dicha estructura, y en la que nuestro CSS no afecte al CSS exterior, ni desde el CSS exterior afecta al CSS interior, algo que los desarrolladores llevan buscando años de forma nativa.
Los módulos ECMAScript (ESModules o ESM) son otra de las características que hace posible que existan los WebComponents. Se trata de un estándar de Javascript, que permite organizar elementos de nuestro código Javascript (constantes, funciones, clases, etc...) en módulos y exportarlos, para ponerlos a disposición de otro archivo Javascript que quiera importarlos.
Estos import
/export
se pueden hacer directamente desde Javascript a través de los Módulos ESM o incluso desde HTML, utilizando el atributo type
establecido al valor module
:
<script type="module" src="fichero.js"></script>
Este tipo de importación de módulos es equivalente al import "./fichero.js";
que podemos realizar desde Javascript y nos puede servir para cargar WebComponents directamente desde HTML.
Nota: En alguna ocasión es posible que nos encontremos una característica llamada Imports HTML. En algún momento llegó a formar parte de WebComponents, pero finalmente fue descartada y marcada como obsoleta, a favor de los Módulos ESM, una característica más moderna y potente.
Los módulos ESM anteriormente mencionados, son la forma nativa de importar ficheros .js
desde Javascript o HTML. Sin embargo, sería genial poder hacer lo mismo con ficheros .json
, .css
o incluso .html
. Esa es la idea de JSON Modules, CSS Modules y HTML Modules, que permitirán importar en objetos Javascript, objetos CSSStyleSheet
y elementos del DOM, respectivamente.
Por ejemplo, observa la siguiente línea de código:
import songs from "./songs.json" assert { type: "json" };
Esta sería la forma de importar, de forma estática un fichero JSON desde Javascript. Ten en cuenta que se añade una terminación assert
mediante la cuál se le indica el tipo de dato importado, que en nuestro caso es un fichero .json
. De la misma forma, podríamos hacerlo con un import dinámico:
const songs = await import("songs.json", { assert: { type: "json" } });
De la misma forma, HTML Modules y CSS Modules (ojo, no confundir con CSS Modules) serán implementaciones nativas del navegador para permitir importar archivos HTML o CSS, al igual que el ejemplo de JSON anterior.
Estas especificaciones aún están en fase experimental, pero van soportándose poco a poco:
Los CSS Scopes forman parte de las características que surgen a raíz del CSS en los WebComponents, donde podemos dar estilo a partes que sólo tienen sentido en el contexto de WebComponents: Shadow DOM, Custom Elements, slots, etc...
Tenemos las siguientes pseudoclases y pseudoelementos CSS:
:host
:host()
:host-context()
::slotted()
::part()
Este último pseudoelemento forma parte de las denominadas CSS Shadow Parts, una especificación que nos provee una forma de exponer partes de un componente para poder darle estilo desde su exterior.
Estas son las características principales que forman parte de los llamados WebComponents. Cada una de ellas es una característica independiente, no obligatoria en un WebComponent. Sin embargo, la verdadera potencia de todas ellas es la posibilidad de unirlas y utilizarlas combinadas para crear potentes componentes web, como iremos viendo más adelante.
Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.
Puedes encontrar más sobre mi en Manz.dev