DEV Community

loading...
Cover image for Introduction to Custom [HTML] Elements (CSS ART)

Introduction to Custom [HTML] Elements (CSS ART)

Michael Salaverry
Using React and Node.js to create reliable tools for others.
・3 min read

What are Custom [HTML] Elements?

Custom Elements are reusable html elements which can encapsulate implementation details into components. Custom Elements are part of the Web Component spec, which is supported by all the major browsers. Custom Elements can be used to bring the component model of React/Angular/Vue to the native web platform without any added dependencies costing valuable network capacity.

What do Custom Elements look like?

Here's an example:

For this example, and in honor of the current Jewish Holiday of Hanukkah, I decided to create a Custom Element for Menorah lights. A menorah has 9 spaces for lights (candles or oil lamps) in total. Each night of Hanukkah, we ignite one more light using the helper light, the shamash. The shamash is always a bit taller than the rest.

Let's take a look at the HTML to see what makes this special:

Rather than rewrite the same HTML 9 times (span>img.candle), I created one reusable custom element for a candle. A "candle-el" can be (lit or unlit) and (normal or shamash). We can create custom attributes on custom elements which can modify that element's styling, behavior, or contents. In this case, each candle listens for the "lit" and the "shamash" attributes to see if it needs to have different styling. I want this to work like the "checked" attribute on HTMLInputElements.

(Homework idea: Click "edit on codepen" and try adding and removing "lit" from the various candle elements in the codepen to see how it changes the styling.)

How do I get started with Custom Elements?

Custom Elements are probably built into your browser, and require no transpilation/bundling/etc, so all you'll need is your browser and a text editor. Codepen is great for this.

Since the appeal of Custom Elements is no dependencies, let's try getting started without any frameworks. While Custom Elements are a useful tool even in a React/Angular/Vue project, we don't need those to get started.

To begin with, we'll need some experience with Javascript. Web Components are built by defining Custom Elements in Javascript. Let's take a look at the Javascript from the example.

The line at the bottom of the Javascript file defines the Custom Element for use in our HTML.

customElements.define(
  /*custom element name=*/"candle-el", 
  /*Javascript class for the custom element=*/Candle
);
Enter fullscreen mode Exit fullscreen mode

The Javascript class must extend an HTMLElement. Within the constructor, we need to call super() and create a shadow DOM root. Later on in the constructor, we need to append the elements within the Custom Element to that shadow DOM root. The shadow DOM root is how we encapsulate the HTML and CSS for the custom element. That shadow root isolates the component from its siblings and parents. You can see this if you inspect element on any candle.

Custom Elements are mostly created with Javascript within the constructor. As you can see, I used document.createElement Element.appendChild and Element.[has/set/get]Attribute through out the constructor to create the elements. This is vanilla Javascript, available without Custom Elements as well. As an aside, React also uses document.createElement to create elements for rendering into the DOM.

Conclusion

Web Components are a standardized and future proof tool for Frontend Web Developers to build consistent experiences. With just a bit of vanilla (ordinary) Javascript, HTML, and CSS, we can create well encapsulated, reusable, and fast loading Custom Elements which can be used across projects and frameworks.

More resources

Discussion (2)

Collapse
nuwannnz profile image
Nuwan Karunarathna

Also, Lit-Element is a nice library from Google for building with custom HTML elements

Collapse
barakplasma profile image
Michael Salaverry Author

I also like the decorators Lit-Element provides for some of the methods needed to use Custom Elements