This content originally appeared on Bits and Pieces - Medium and was authored by Lina Suodyte
Recently, while learning about the intricacies of micro frontends architecture, I came across an example of Shadow DOM. I started reading about it more and realized that it was a very simple-to-use technology that could be very beneficial when combining UI elements on the client side. So let’s take a quick look at what it is.
Shadow DOM falls under the umbrella of Web Components. It is a set of APIs allowing us to create reusable custom elements with their functionality encapsulated away from the rest of the code. There are other Web Components, such as Custom Elements and HTML templates (their main tasks can be easily guessed just by looking at their names) but in this article, I will focus on Shadow DOM.
Simply put, Shadow DOM allows a hidden DOM sub-tree to be attached to a regular DOM tree. It can be attached to any elements in the DOM and treated and styled as regular DOM elements.
But what is so “shadow” about it then, one might ask?
Shadow DOM is a self-contained block of code within a regular DOM that has its scope. Its main task is to keep the element’s styles and functionality encapsulated. That means that no styles will leak from the Shadow DOM sub-tree to the main DOM and no global styles will affect the elements of the Shadow DOM, even if some of them happen to have the same names.
Of course, iFrames could be used in this case as well. However, loading an iFrame is a very expensive operation, which would affect performance. Also, iFrames are bad for SEO reasons because crawlers see them as a different page instead of an element, which is being included on its parent page. This means that it could happen that content, seen by the user might not be indexed as part of the website. This problem can be avoided by using Shadow DOM because from the perspective of a crawler, the element would be seen as part of the DOM tree.
Usecases
But what are good use cases for this technology?
Let’s say different teams work on different elements that are rendered on the same page. These elements are stylistically and functionally independent and do not need to know about each other’s inner workings. Using Shadow DOM to render them would allow us to include them into the DOM and prevent any unexpected leakage of styles or functionality without extra alignment among the teams.
Also, this technology is worth considering if we need to insert a new component into a legacy application and want to make sure that no styles or functionality will collide.
Lastly, separating components into Shadow DOM sub-trees helps us mentally organize elements into self-contained blocks. Even though in the end they’re all rendered as one DOM, keeping elements conceptually independent helps us reason about them as separate units and keep their styles and functionality clean and separated from each other and the rest of the page.
Usage
To implement a Shadow DOM, we do not need to install any extra packages. Creating a Shadow DOM subtree is as simple as calling the Element.attachShadow() method on a DOM element that we want to have as its root. This method accepts an object with the key mode, which can be set to closed or open. The best practice is to set it to open because it helps crawlers read it (which would solve the above-mentioned problem that we face when using iFrames). If it is set to closed, the Shadow DOM cannot be manipulated by scripts from outside but also its contents will not be considered for SEO.
const myShadowDOM = myRegularDOMElement.attachShadow({mode: 'open'});
Element.attachShadow() method returns a reference to the Shadow DOM so we can assign it to a variable.
Once the Shadow DOM is ready, we can treat it as a regular DOM element. For example, we can select it or add styles to it.
myShadowDOM.innerHTML = '<p>Hello from the shadows!</p>';
myShadowDOM.style.color = 'pink';
Of course, usually we would not use inline styling. It is also possible to attach an external style sheet to a Shadow DOM. It can be done as follows:
const externalStyles = document.createElement('link');
externalStyles.setAttribute('rel', 'stylesheet');
externalStyles.setAttribute('href', 'myShadowDOMStyles.css');
myShadowDOM.appendChild(externalStyles);
It is worth noting that any number of such sub-trees can be attached to a DOM. In the case of multiple sub-trees, each of them would have its shadow root with styles and functionality, separated from the main DOM and other Shadow DOMs.
Drawbacks
It all looks easy and fun but surely, there must be some drawbacks. As usual, it all depends on the use case.
First, Shadow DOM is supported by Firefox (63 and onwards), Chrome, Opera, Safari, and Edge (75 or higher). For it to work in older browsers, a polyfill will be needed.
Also, for this technology to work, JavaScript is required. It means that load times might be impacted. It could also be an issue if, for example, a user deactivates JavaScript for accessibility reasons. In that case, the element will not be rendered and the user might miss crucial information. This also means that Shadow DOM elements cannot be server-side rendered.
In addition to that, because by design styles of Shadow DOM are encapsulated, they do not work with styling approaches that use global CSS classes. It is also hard to share styles between two shadow sub-trees. Every Shadow DOM sub-tree would need its styles and it could result in some CSS duplication.
However, if these drawbacks are not a major concern, Shadow DOM is so simple and easy to use that it is tempting to at least play with it and see how it works in practice.
Shadow DOM: A Quick and Simple Introduction was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Bits and Pieces - Medium and was authored by Lina Suodyte
Lina Suodyte | Sciencx (2022-05-12T07:36:14+00:00) Shadow DOM: A Quick and Simple Introduction. Retrieved from https://www.scien.cx/2022/05/12/shadow-dom-a-quick-and-simple-introduction/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.