Web Components - Part 1
Published: 2020-09-05 15:42:48

<!-- wp:image -->
<figure class="wp-block-image"><img src="https://cdn-images-1.medium.com/max/800/0*fOqlfB6UV7lqmAKg.jpg" alt=""/><figcaption>Web components logo</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Front-end web development has become incredibly complex over the years. Back in the day the only things you needed to become a front-end web developer was <code>HTML</code>, <code>CSS</code> and some basic <code>JavaScript</code> or if you were fancy then you would learn <code>jQuery</code>. But the issue ‘back in the day’ was that browsers would rendering of elements would be different so as web developer we would have to use hacks to make things look acceptable.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Today, we have a number of front-end libraries/frameworks that offer front-end developers some incredible super powers, the problem with them is that most of us don’t utilise all the features that we import with the libraries/frameworks. To make things even worse depending on the preference of the developers working on a project you end up using different libraries for different projects. Wouldn’t it be nice if we could have a set of components that could be used across projects and across libraries/frameworks?</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>NB: Henceforth when I <code>libraries</code> I am referring to <code>libraries/frameworks</code></p></blockquote>
<!-- /wp:quote -->

<!-- wp:paragraph -->
<p>Enter</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"wide"} -->
<figure class="wp-block-image alignwide"><img src="https://cdn-images-1.medium.com/max/800/1*0S9pD4xQe-OSGiS13v0DzQ.png" alt=""/><figcaption>Web Components title surrounded by fireworks</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>[Insert Bollywood Explosions here]</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Web Components were originally introduced in 2011 and browsers started implementing them much later.</p>
<!-- /wp:paragraph -->

<!-- wp:separator {"className":"is-style-dots"} -->
<hr class="wp-block-separator is-style-dots"/>
<!-- /wp:separator -->

<!-- wp:heading {"level":3} -->
<h3>What are Web Components?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Web components are a set of web APIs that allow developers to make encapsulated components that have their own set of functions and styling.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Web components are made up of</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>Custom Elements</li><li>Shadow DOM</li><li>ES Modules</li><li>HTML Templates</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>For this article I will be focusing on Custom Elements.</p>
<!-- /wp:paragraph -->

<!-- wp:separator {"className":"is-style-dots"} -->
<hr class="wp-block-separator is-style-dots"/>
<!-- /wp:separator -->

<!-- wp:heading {"level":3} -->
<h3>Custom Elements</h3>
<!-- /wp:heading -->

<!-- wp:heading {"level":4} -->
<h4>The need for Custom&nbsp;Elements</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>HTML provides a number of tags that have been serving the web well but the issue comes in when you try to get a consistent look and feel for various HTML tags. CSS tries to solve this by having a global style sheet that houses all the UI styles, however, this gets very difficult to manage with multiple developers since most developers would end up writing styles at the bottom of CSS files which makes it difficult to manage the styling.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>To address this various frameworks and libraries have come up such as React and VueJS that let you encapsulate/scope styles. This solution of course works well when you have the freedom of importing libraries but what if you would like to achieve the same without using a particular library or framework. This is where <code>Custom Elements</code> in. As a PoC lets look at how an ecommerce front-end would look like with <code>Custom Elements</code>&nbsp;.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>The Design</h4>
<!-- /wp:heading -->

<!-- wp:image -->
<figure class="wp-block-image"><img src="https://cdn-images-1.medium.com/max/1200/1*98CJQ4f42SWlPMYTMNS1SQ.jpeg" alt=""/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Very simple design of an e-commerce store that we will be implementing to figure out how <code>Custom Elements</code> work.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Basic HTML Implementation</p>
<!-- /wp:paragraph -->

https://codepen.io/davinderpal/pen/abNwoBp

<!-- wp:paragraph -->
<p>CodePen showing implementation using basic HTML</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>Converting To Custom&nbsp;Elements</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We have tried as much as possible to provide semantic meaning to the markup but there are places that the tag chosen doesn’t make sense. If a different developer was to continue this project they would would probably use different mark up, e.g. instead of using a <code>p</code> tag for the price they could use a <code>div</code>&nbsp;, this won’t cause any issues in styling since we are using the classes to do the styling but it does make our codebase very inconsistent, therefore, harder to manage.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Instead we could convert the mark up to a custom element and abstract the implementation. So having a custom element such as</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">&lt;shop-product<br>  image='<a href="https://source.unsplash.com/200x200/?shoes%27" rel="noreferrer noopener" target="_blank">https://source.unsplash.com/200x200/?shoes'</a><br>  name='Nikey Shoes'<br>  price='$40'<br>  rating='1'<br>  variants='100'<br>&gt;&lt;/shop-product&gt;</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>would ensure that any developer creating a new shop page would have a consistent way of describing the elements. There is an added advantage of making our code base slightly more readable.</p>
<!-- /wp:paragraph -->

https://codepen.io/davinderpal/pen/bGpaNpG

<!-- wp:paragraph -->
<p>As you can see from the Pen above both implementations look exactly the same to the end-user, but the below one has a more consistent codebase with less chances of a different developer changing markup in a different page. This also makes the code reusable across pages and even sites.</p>
<!-- /wp:paragraph -->

<!-- wp:separator {"className":"is-style-dots"} -->
<hr class="wp-block-separator is-style-dots"/>
<!-- /wp:separator -->

<!-- wp:heading {"level":3} -->
<h3>The Implementation</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>To register a custom element you have to <code>JS</code> with the <code>window.customElements.define</code> (or <code>customElements.define</code>)function which takes in 2 required arguments and 1 optional argument.</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>The first argument is the <code>name</code> of the custom element that you are creating. The docs require that the <code>name</code> of the custom element needs to include a hyphen <code>—</code> in its name. This is usually a string.</li><li>The second argument is the <code>constructor</code> that defines how the element will actually be implemented. This is usually a class.</li><li>The third argument is an <code>options</code> object. This is out of scope for this article but in the coming articles I will be covering this more.</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>The way <code>JS</code> is structured you will need to declare the implementation class before trying to register the custom element.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The implementation class extends the <code>HTMLElement</code> class and as such inherits all the functions and events that a normal HTML element would have. Within the new class we only require to provide the <code>constructor</code> which starts by calling the <code>super()</code> function.</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">class Product extends HTMLElement {<br>  constructor () {<br>    super()<br>  }<br>}</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>Within the <code>constructor</code> you would create the HTML elements that are required for the implementation of the custom element. This code can be seen within the CodePen above.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>Conclusion</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Creating custom elements really helps have consistent and reusable code for web applications. This also lets you hide some of the inner workings which let developers who are not very familiar with front-end development still write front-end code.</p>
<!-- /wp:paragraph -->