{"id":1957,"date":"2019-12-05T15:01:47","date_gmt":"2019-12-05T14:01:47","guid":{"rendered":"https:\/\/www.codemotion.com\/magazine\/uncategorized\/the-dom-and-its-shadow\/"},"modified":"2021-12-23T15:20:09","modified_gmt":"2021-12-23T14:20:09","slug":"the-dom-and-its-shadow","status":"publish","type":"post","link":"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/","title":{"rendered":"The DOM and its shadow"},"content":{"rendered":"<p>Nowadays, most <strong>frontend web developers<\/strong> build their <span id=\"urn:enhancement-e730c230\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/user_interface\">UI<\/span> with well-known libraries and frameworks such as <strong><span id=\"urn:enhancement-46d8c6c\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/react\">React<\/span><\/strong>, <strong>Angular<\/strong>, <strong>Vue<\/strong>, and so on. Maybe many developers have almost forgotten how to dynamically create <span id=\"urn:enhancement-fcf2ffdf\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/html_element\">HTML elements<\/span> by accessing the <strong><span id=\"urn:enhancement-8bc87f6d\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">Document Object Model<\/span><\/strong> (<strong><span id=\"urn:enhancement-5b029346\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span><\/strong>). In fact, almost all these cool libraries abstract the <span id=\"urn:enhancement-3d0f7608\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span> and provide their own model to produce <span id=\"urn:enhancement-528b9366\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/html_element\">HTML elements<\/span>. Some even virtualize the <span id=\"urn:enhancement-fc56cb2d\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span> to optimize access.<\/p>\n<p>Why then should a modern frontend web developer keep the <span id=\"urn:enhancement-267952d7\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span> in mind?\u00a0 After all, it sounds like low-level stuff that <span id=\"urn:enhancement-af622bb4\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/user_interface\">UI<\/span> libraries handle efficiently.<\/p>\n<p>That&#8217;s certainly how it looks, and for the most part, how it is, but the <span id=\"urn:enhancement-9e3ee156\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span> always remains present.\u00a0 Any <span id=\"urn:enhancement-9b846b33\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/user_interface\">UI<\/span> model eventually maps your code to the <span id=\"urn:enhancement-c931555c\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span>, retaining its congenital defects in the process.<\/p>\n<h2 id=\"5bll3\">The problem with the DOM<\/h2>\n<p>Most <span id=\"urn:enhancement-9e719375\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/user_interface\">UI<\/span> libraries have made us accustomed to thinking of the <span id=\"urn:enhancement-b7714dc2\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/user_interface\">UI<\/span> as a puzzle of components. This architecture is really awesome and promotes reuse, one of the most avidly-pursued principles of software development. On the other hand, the <span id=\"urn:enhancement-aa47b4f2\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span> has a major flaw that hinders composition and reuse: <strong>it is globally accessible<\/strong>.<\/p>\n<p>It doesn\u2019t matter where your <span id=\"urn:enhancement-a20d3b5f\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/user_interface\">UI<\/span> element comes from &#8211; React, Angular, plain JavaScript&#8230; When your element is appended to the <span id=\"urn:enhancement-a96898fb\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span>, it can be accessed from any JavaScript code or <span id=\"urn:enhancement-f16435bf\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/cascading_style_sheets\">CSS<\/span> rules, and its internal structure can be changed.<\/p>\n<p><strong>The <span id=\"urn:enhancement-bba0e680\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span> is like a global variable. And all we know how bad global variables are.<\/strong><\/p>\n<p>As a result, when you add your <span id=\"urn:enhancement-23c390e6\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/user_interface\">UI<\/span> <span id=\"urn:enhancement-5910d96f\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/component-based_software_engineering\">component<\/span> to the <span id=\"urn:enhancement-8079156d\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span>, the UI may lose its alleged reusability due to the <span id=\"urn:enhancement-7f4472a4\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span>\u2019s lack of <span id=\"urn:enhancement-916f49e1\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/encapsulation_object-oriented_programming\">encapsulation<\/span>.<\/p>\n<p>Let\u2019s explore this point with an example.<\/p>\n<p>Say you have created an awesome banner to invite your JavaScript community to your next great meetup. You want to distribute this banner to other websites so that they can all spread the word. You can build this banner in many ways, with pure <span id=\"urn:enhancement-18ac9c2\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/html\">HTML<\/span> or using the <span id=\"urn:enhancement-2fcf3395\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/user_interface\">UI<\/span> library you prefer. It doesn\u2019t really matter &#8211; regardless of how you build, the output will be a few elements on the <span id=\"urn:enhancement-198e2b2d\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span>.<\/p>\n<p>For our purposes here, assume that this is the <span id=\"urn:enhancement-6676e469\" class=\"textannotation disambiguated wl-creative-work\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/javascript\">JavaScript<\/span> code that creates your banner:<\/p>\n<pre>function createBanner(elementId) {<br \/> const banner = document.getElementById(elementId);<br \/> banner.innerHTML = `<br \/>&lt;style&gt;<br \/>#box {<br \/>-webkit-box-shadow: 5px 5px 15px 5px #000000;<br \/>box-shadow: 5px 5px 15px 5px #000000;<br \/>font-family: Verdana, Geneva, sans-serif;<br \/>padding: 10px;<br \/>text-align: center;<br \/>width: 80%;<br \/>}<br \/>h3 {<br \/>font-size: 25px;<br \/>color: #5F36FF;<br \/>}<br \/>#description {<br \/>font-weight: bold;<br \/>font-size: 18px;<br \/>color: #6B6B6B;<br \/>}<br \/>#finalMessage {<br \/>font-weight: bold;<br \/>color: #6B2E63;<br \/>text-decoration: underline solid rgb(68, 68, 68);<br \/>}<br \/>&lt;\/style&gt;<br \/>&lt;div id=\"box\"&gt;<br \/>&lt;h3&gt;Join our awesome <span id=\"urn:enhancement-42504a60\" class=\"textannotation disambiguated wl-creative-work\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/javascript\">JavaScript<\/span> meetup&lt;\/h3&gt;<br \/>&lt;p id=\"description\"&gt;You will learn the latest amazing way to forget <span id=\"urn:enhancement-d0b92a17\" class=\"textannotation disambiguated wl-creative-work\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/javascript\">JavaScript<\/span>.&lt;p&gt;<br \/>&lt;p id=\"finalMessage\"&gt;Don't miss it!&lt;\/p&gt;<br \/>&lt;\/div&gt;<br \/> `;<br \/>}<\/pre>\n<p>We&#8217;ve used plain <span id=\"urn:enhancement-bda0bb35\" class=\"textannotation disambiguated wl-creative-work\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/javascript\">JavaScript<\/span> here: a simple function that takes the identifier of an element in the <span id=\"urn:enhancement-fa9d28f1\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span> and attaches some <span id=\"urn:enhancement-dd665333\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/markup_language\">markup<\/span> to it. If this code is stored in a file named <em>banner.js<\/em>, you can use it within an <span id=\"urn:enhancement-8dd351a8\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/html\">HTML<\/span> page in the following way:<\/p>\n<pre>&lt;!DOCTYPE html&gt;<br \/>&lt;html lang=\"en\"&gt;<br \/>&lt;head&gt;<br \/>  &lt;meta charset=\"UTF-8\"&gt;<br \/>  &lt;<span id=\"urn:enhancement-1c45cf82\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/scripting_language\">script<\/span> src=\"banner.js\"&gt;&lt;\/<span id=\"urn:enhancement-c733929f\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/scripting_language\">script<\/span>&gt;<br \/>  &lt;<span id=\"urn:enhancement-7636f0f4\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/scripting_language\">script<\/span>&gt;<br \/>    window.onload = function() {<br \/>      createBanner(\"banner\")<br \/>    };<br \/>  &lt;\/<span id=\"urn:enhancement-85870ea6\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/scripting_language\">script<\/span>&gt;<br \/>&lt;\/head&gt;<br \/>&lt;body&gt;<br \/>  &lt;div id=\"banner\"&gt;&lt;\/div&gt;<br \/>&lt;\/body&gt;<br \/>&lt;\/<span id=\"urn:enhancement-f250ec7a\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/html\">html<\/span>&gt;<\/pre>\n<p>This page will be rendered as shown in the following image:<\/p>\n<figure class=\"image regular \"><picture><source srcset=\"https:\/\/codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/image1_f7e666df0a1da568148802fc9102c063_800.png 1x\" media=\"(max-width: 768px)\" \/><source srcset=\"https:\/\/codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/image1_f7e666df0a1da568148802fc9102c063_800.png 1x\" media=\"(min-width: 769px)\" \/><img decoding=\"async\" src=\"https:\/\/codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/image1_f7e666df0a1da568148802fc9102c063_800.png\" alt=\"\" \/><\/picture><\/figure>\n<p>Now, say that one of your &#8216;friend&#8217; websites uses a <span id=\"urn:enhancement-651a1a60\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/cascading_style_sheets\">CSS<\/span> rule like the following:<\/p>\n<pre>h3 {<br \/>  text-transform: uppercase;<br \/>  background: #0A59FA;<br \/>}<\/pre>\n<p>As a result of applying this rule, your banner will look like this:<\/p>\n<figure class=\"image regular \"><picture><source srcset=\"https:\/\/codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/image3_0cbd91400a5f0b7defd688bb72143702_800.png 1x\" media=\"(max-width: 768px)\" \/><source srcset=\"https:\/\/codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/image3_0cbd91400a5f0b7defd688bb72143702_800.png 1x\" media=\"(min-width: 769px)\" \/><img decoding=\"async\" src=\"https:\/\/codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/image3_0cbd91400a5f0b7defd688bb72143702_800.png\" alt=\"\" \/><\/picture><\/figure>\n<p>Not so good &#8211; this is not how you wanted your banner to look.<\/p>\n<p>Even worse, imagine that somewhere in one of those other websites there is a <span id=\"urn:enhancement-5274649c\" class=\"textannotation disambiguated wl-creative-work\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/javascript\">JavaScript<\/span> code like this:<\/p>\n<pre>document.getElementById(\"description\").innerText = \"I don't like <span id=\"urn:enhancement-cc957766\" class=\"textannotation disambiguated wl-creative-work\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/javascript\">JavaScript<\/span>!\";<\/pre>\n<p>Your banner will now look like this:<\/p>\n<figure class=\"image regular \"><picture><source srcset=\"https:\/\/codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/image2_ffc584fe5833b31d8d568554805ed75a_800.png 1x\" media=\"(max-width: 768px)\" \/><source srcset=\"https:\/\/codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/image2_ffc584fe5833b31d8d568554805ed75a_800.png 1x\" media=\"(min-width: 769px)\" \/><img decoding=\"async\" src=\"https:\/\/codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/image2_ffc584fe5833b31d8d568554805ed75a_800.png\" alt=\"\" \/><\/picture><\/figure>\n<p>Eventually, you will decide that your banner is not safe. Its inner structure can be manipulated like any other element in the <span id=\"urn:enhancement-7b10642e\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span>.<\/p>\n<p><strong>How can you protect your work from accidental or intentional changes from the external environment?<\/strong> How can you guarantee the <span id=\"urn:enhancement-529084ce\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/encapsulation_object-oriented_programming\">encapsulation<\/span> of your work?<\/p>\n<h3 id=\"7t6gd\">The Shadow DOM<\/h3>\n<p>Traditionally, the <span id=\"urn:enhancement-2f09c4ac\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span> <span id=\"urn:enhancement-974281fc\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/encapsulation_object-oriented_programming\">encapsulation<\/span> problem has been tackled by using iframes. Put all the code for your banner into an iframe and it is <span id=\"urn:enhancement-4962ec12\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/class_computer_programming\">protected<\/span>. That solution solves one problem, but it introduces others. In fact, there is a simple and elegant solution for the <span id=\"urn:enhancement-57eaed75\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/encapsulation_object-oriented_programming\">encapsulation<\/span> problem, and its name is <strong>Shadow <span id=\"urn:enhancement-c9c51608\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span><\/strong>. It is a set of <strong>standard <span id=\"urn:enhancement-71af12df\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/application_programming_interface\">APIs<\/span><\/strong> that enable the <span id=\"urn:enhancement-8596be32\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/encapsulation_object-oriented_programming\">encapsulation<\/span> of a portion of the <span id=\"urn:enhancement-7300a217\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span> inside the <span id=\"urn:enhancement-8ed1708b\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span> of an HTML page. This allows you to <strong>create a sort of private <span id=\"urn:enhancement-7183a974\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span> for an <span id=\"urn:enhancement-b38571c7\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/html_element\">HTML element<\/span><\/strong>. In other words, it enables a local <span id=\"urn:enhancement-895924c9\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span> in contrast with the <span id=\"urn:enhancement-7c14d201\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/global_variable\">global<\/span> <span id=\"urn:enhancement-410d1f10\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span>, just like <span id=\"urn:enhancement-fd74268b\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/global_variable\">global<\/span> and local <span id=\"urn:enhancement-6ca130f0\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/variable_computer_science\">variables<\/span>. The trick is very simple. Look at this snippet of code:<\/p>\n<pre>function createBanner(elementId) {<br \/>  const banner = document.getElementById(elementId);<br \/><br \/>  banner.attachShadow({mode: \"open\"});<br \/><br \/>  banner.shadowRoot.innerHTML = `<br \/>    &lt;style&gt;<br \/>      \/\/ The same stuff as before...<br \/>    &lt;\/div&gt;<br \/>  `;<br \/>}<\/pre>\n<p>We just invoked the <em>attachShadow()<\/em> <span id=\"urn:enhancement-2db153ab\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/method_computer_programming\">method<\/span> of the element to attach the Shadow <span id=\"urn:enhancement-81e88d37\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span>. This <span id=\"urn:enhancement-cbc87a21\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/method_computer_programming\">method<\/span> is available for most <span id=\"urn:enhancement-692c1ab8\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/html_element\">HTML elements<\/span>. It attaches a node that represents the root of the local <span id=\"urn:enhancement-626716ff\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span> to the <em>banner<\/em> element. This root node can be accessed through the <em>shadowRoot<\/em> property. The content that was previously directly appended to the <em>banner<\/em> element is now appended to the <em>shadowRoot<\/em> property.<\/p>\n<h2 id=\"42pb5\">Open and closed Shadow DOM<\/h2>\n<p>As you\u2019ve seen, a very little change to your code makes your banner impenetrable. Well actually, not quite.<\/p>\n<p>You noticed that we passed a parameter to the <em>attachShadow()<\/em> <span id=\"urn:enhancement-1628124a\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/method_computer_programming\">method<\/span>.<\/p>\n<pre>banner.attachShadow({mode: \"open\"});<\/pre>\n<p>This is a literal object with the <em>mode<\/em> property set to the <em>open<\/em> value. This object allows you to specify the creation mode of your Shadow <span id=\"urn:enhancement-ce17f397\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span> and it is mandatory. In the example above, we asked for an open Shadow <span id=\"urn:enhancement-b96ec619\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span>. This means that the elements that build up our banner will be <span id=\"urn:enhancement-45dc51d9\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/class_computer_programming\">protected<\/span> against accidental interference from <span id=\"urn:enhancement-35f8ac33\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/cascading_style_sheets\">CSS<\/span> rules or <span id=\"urn:enhancement-282fbde3\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span> manipulation, but they remain <span id=\"urn:enhancement-9a2a12d9\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/accessibility\">accessible<\/span> from the outside world. In fact, you can access the elements through the <em>shadowRoot<\/em> property, as shown below:<\/p>\n<pre>const bannerRoot = document.getElementById(\"banner\").shadowRoot;<br \/>bannerRoot.getElementById(\"description\")<br \/>  .innerText = \"I don't like JavaScript!\";<\/pre>\n<p>So, the internal parts of your banner are still <span id=\"urn:enhancement-73063773\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/accessibility\">accessible<\/span>, but it has to be done intentionally. By attaching the Shadow <span id=\"urn:enhancement-7c551952\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span> with the <em>open<\/em> mode you chose for this to be possible. If on the other hand you don\u2019t want access to be possible, if you want the internal workings of your banner to be invisible to the rest of the world, attach a Shadow <span id=\"urn:enhancement-f8fbaa7a\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span> with the <em>closed<\/em> mode:<\/p>\n<pre>banner.attachShadow({mode: \"closed\"});<\/pre>\n<p>Now, your banner will be impregnable!<\/p>\n<h2 id=\"80o3\">Conclusion<\/h2>\n<p>As we saw inthis article, the <span id=\"urn:enhancement-2adc500f\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span> most developers know is not the best structure for hosting a composable <span id=\"urn:enhancement-aae819ba\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/user_interface\">UI<\/span>. Its open <span id=\"urn:enhancement-383e7726\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/accessibility\">accessibility<\/span> exposes your <span id=\"urn:enhancement-5bb4e6bc\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/user_interface\">UI<\/span> elements to possible undesirable conflicts. This factor clashes with the principle of composability and reusability we all want for our <span id=\"urn:enhancement-fcd8780\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/user_interface\">UI<\/span> elements. We have explored an example of such possible conflict, but we have also discovered that a simple and standard solution is available. The lack of <span id=\"urn:enhancement-24c739b9\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/encapsulation_object-oriented_programming\">encapsulation<\/span> of the classic <span id=\"urn:enhancement-a012bd7d\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span> can be overcome by using the Shadow <span id=\"urn:enhancement-1794f1e\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/document_object_model\">DOM<\/span>. A few JavaScript statements can save your work from external interference and make your <span id=\"urn:enhancement-6159f30c\" class=\"textannotation disambiguated wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/user_interface\">UI<\/span> elements really reusable.<\/p>\n<p><!-- strchf script --><script>        if(window.strchfSettings === undefined) window.strchfSettings = {};    window.strchfSettings.stats = {url: \"https:\/\/codemotion.storychief.io\/the-dom-and-its-shadow?id=1221907092&type=2\",title: \"The DOM and its shadow\",id: \"66543c6c-96d5-4792-a44b-49339654b7a1\"};            (function(d, s, id) {      var js, sjs = d.getElementsByTagName(s)[0];      if (d.getElementById(id)) {window.strchf.update(); return;}      js = d.createElement(s); js.id = id;      js.src = \"https:\/\/d37oebn0w9ir6a.cloudfront.net\/scripts\/v0\/strchf.js\";      js.async = true;      sjs.parentNode.insertBefore(js, sjs);    }(document, 'script', 'storychief-jssdk'))    <\/script><!-- End strchf script --><\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>Nowadays, most frontend web developers build their UI with frameworks like React, Angular, Vue, and similar. Maybe many of them almost forgot the way to dynamically create HTML elements by accessing the Document Object Model (DOM). However, DOM is basically global, and like any global variable, it has many drawbacks. In this article you&#8217;ll learn how to protect your work from accidental or intentional changes from an external environment, to guarantee proper encapsulation. How? Using the Shadow DOM.<\/p>\n","protected":false},"author":76,"featured_media":1958,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_editorskit_title_hidden":false,"_editorskit_reading_time":4,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","_uag_custom_page_level_css":"","_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","footnotes":""},"categories":[8],"tags":[63],"collections":[],"class_list":{"0":"post-1957","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-javascript","8":"tag-html","9":"entry"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.9 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Shadow DOM: how you should use it - Codemotion<\/title>\n<meta name=\"description\" content=\"Learn how to manipulate elements of a web page by guaranteeing proper encapsulation. How? By using the Shadow DOM.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"The DOM and its shadow\" \/>\n<meta property=\"og:description\" content=\"Learn how to manipulate elements of a web page by guaranteeing proper encapsulation. How? By using the Shadow DOM.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/\" \/>\n<meta property=\"og:site_name\" content=\"Codemotion Magazine\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Codemotion.Italy\/\" \/>\n<meta property=\"article:published_time\" content=\"2019-12-05T14:01:47+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-12-23T14:20:09+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"675\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Andrea Chiarelli\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:site\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andrea Chiarelli\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/\"},\"author\":{\"name\":\"Andrea Chiarelli\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/6636c3b8f0c7f2f137f173229d6579d4\"},\"headline\":\"The DOM and its shadow\",\"datePublished\":\"2019-12-05T14:01:47+00:00\",\"dateModified\":\"2021-12-23T14:20:09+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/\"},\"wordCount\":1038,\"publisher\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000.jpg\",\"keywords\":[\"HTML\"],\"articleSection\":[\"JavaScript\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/\",\"name\":\"Shadow DOM: how you should use it - Codemotion\",\"isPartOf\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000.jpg\",\"datePublished\":\"2019-12-05T14:01:47+00:00\",\"dateModified\":\"2021-12-23T14:20:09+00:00\",\"description\":\"Learn how to manipulate elements of a web page by guaranteeing proper encapsulation. How? By using the Shadow DOM.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/#primaryimage\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000.jpg\",\"contentUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000.jpg\",\"width\":1200,\"height\":675,\"caption\":\"The DOM and its shadow\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.codemotion.com\/magazine\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Frontend\",\"item\":\"https:\/\/www.codemotion.com\/magazine\/frontend\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"The DOM and its shadow\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#website\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/\",\"name\":\"Codemotion Magazine\",\"description\":\"We code the future. Together\",\"publisher\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.codemotion.com\/magazine\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#organization\",\"name\":\"Codemotion\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png\",\"contentUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png\",\"width\":225,\"height\":225,\"caption\":\"Codemotion\"},\"image\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/Codemotion.Italy\/\",\"https:\/\/x.com\/CodemotionIT\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/6636c3b8f0c7f2f137f173229d6579d4\",\"name\":\"Andrea Chiarelli\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/6cdfc954a6d1ba697d417cece2008f4fa62dc06f2cf345e33ecf47b3bbbb6c3e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/6cdfc954a6d1ba697d417cece2008f4fa62dc06f2cf345e33ecf47b3bbbb6c3e?s=96&d=mm&r=g\",\"caption\":\"Andrea Chiarelli\"},\"description\":\"I've been working as a Software Engineer and Technical Writer for over 20 years, using several languages and technologies. I contributed to a few offline and online magazines and wrote a few books. Currently, I'm working in the Technical Experience team at Auth0.\",\"sameAs\":[\"https:\/\/andreachiarelli.it\"],\"url\":\"https:\/\/www.codemotion.com\/magazine\/author\/andrea-chiarelli\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Shadow DOM: how you should use it - Codemotion","description":"Learn how to manipulate elements of a web page by guaranteeing proper encapsulation. How? By using the Shadow DOM.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/","og_locale":"en_US","og_type":"article","og_title":"The DOM and its shadow","og_description":"Learn how to manipulate elements of a web page by guaranteeing proper encapsulation. How? By using the Shadow DOM.","og_url":"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/","og_site_name":"Codemotion Magazine","article_publisher":"https:\/\/www.facebook.com\/Codemotion.Italy\/","article_published_time":"2019-12-05T14:01:47+00:00","article_modified_time":"2021-12-23T14:20:09+00:00","og_image":[{"width":1200,"height":675,"url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000.jpg","type":"image\/jpeg"}],"author":"Andrea Chiarelli","twitter_card":"summary_large_image","twitter_creator":"@CodemotionIT","twitter_site":"@CodemotionIT","twitter_misc":{"Written by":"Andrea Chiarelli","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/#article","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/"},"author":{"name":"Andrea Chiarelli","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/6636c3b8f0c7f2f137f173229d6579d4"},"headline":"The DOM and its shadow","datePublished":"2019-12-05T14:01:47+00:00","dateModified":"2021-12-23T14:20:09+00:00","mainEntityOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/"},"wordCount":1038,"publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000.jpg","keywords":["HTML"],"articleSection":["JavaScript"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/","url":"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/","name":"Shadow DOM: how you should use it - Codemotion","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/#primaryimage"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000.jpg","datePublished":"2019-12-05T14:01:47+00:00","dateModified":"2021-12-23T14:20:09+00:00","description":"Learn how to manipulate elements of a web page by guaranteeing proper encapsulation. How? By using the Shadow DOM.","breadcrumb":{"@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/#primaryimage","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000.jpg","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000.jpg","width":1200,"height":675,"caption":"The DOM and its shadow"},{"@type":"BreadcrumbList","@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/the-dom-and-its-shadow\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.codemotion.com\/magazine\/"},{"@type":"ListItem","position":2,"name":"Frontend","item":"https:\/\/www.codemotion.com\/magazine\/frontend\/"},{"@type":"ListItem","position":3,"name":"The DOM and its shadow"}]},{"@type":"WebSite","@id":"https:\/\/www.codemotion.com\/magazine\/#website","url":"https:\/\/www.codemotion.com\/magazine\/","name":"Codemotion Magazine","description":"We code the future. Together","publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.codemotion.com\/magazine\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.codemotion.com\/magazine\/#organization","name":"Codemotion","url":"https:\/\/www.codemotion.com\/magazine\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","width":225,"height":225,"caption":"Codemotion"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Codemotion.Italy\/","https:\/\/x.com\/CodemotionIT"]},{"@type":"Person","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/6636c3b8f0c7f2f137f173229d6579d4","name":"Andrea Chiarelli","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/6cdfc954a6d1ba697d417cece2008f4fa62dc06f2cf345e33ecf47b3bbbb6c3e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6cdfc954a6d1ba697d417cece2008f4fa62dc06f2cf345e33ecf47b3bbbb6c3e?s=96&d=mm&r=g","caption":"Andrea Chiarelli"},"description":"I've been working as a Software Engineer and Technical Writer for over 20 years, using several languages and technologies. I contributed to a few offline and online magazines and wrote a few books. Currently, I'm working in the Technical Experience team at Auth0.","sameAs":["https:\/\/andreachiarelli.it"],"url":"https:\/\/www.codemotion.com\/magazine\/author\/andrea-chiarelli\/"}]}},"featured_image_src":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000-600x400.jpg","featured_image_src_square":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000-600x600.jpg","author_info":{"display_name":"Andrea Chiarelli","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/andrea-chiarelli\/"},"uagb_featured_image_src":{"full":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000.jpg",1200,675,false],"thumbnail":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000-150x150.jpg",150,150,true],"medium":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000-300x169.jpg",300,169,true],"medium_large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000-768x432.jpg",768,432,true],"large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000-1024x576.jpg",1024,576,true],"1536x1536":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000.jpg",1200,675,false],"2048x2048":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000.jpg",1200,675,false],"small-home-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000.jpg",100,56,false],"sidebar-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000-180x128.jpg",180,128,true],"genesis-singular-images":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000-896x504.jpg",896,504,true],"archive-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000-400x225.jpg",400,225,true],"gb-block-post-grid-landscape":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000-600x400.jpg",600,400,true],"gb-block-post-grid-square":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/12\/piqsels_com-id-zkmif_88db49990920666ce208fe536da187d0_2000-600x600.jpg",600,600,true]},"uagb_author_info":{"display_name":"Andrea Chiarelli","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/andrea-chiarelli\/"},"uagb_comment_info":0,"uagb_excerpt":"Nowadays, most frontend web developers build their UI with frameworks like React, Angular, Vue, and similar. Maybe many of them almost forgot the way to dynamically create HTML elements by accessing the Document Object Model (DOM). However, DOM is basically global, and like any global variable, it has many drawbacks. In this article you'll learn&hellip;","lang":"en","_links":{"self":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/1957","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/users\/76"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/comments?post=1957"}],"version-history":[{"count":3,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/1957\/revisions"}],"predecessor-version":[{"id":12950,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/1957\/revisions\/12950"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media\/1958"}],"wp:attachment":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media?parent=1957"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/categories?post=1957"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/tags?post=1957"},{"taxonomy":"collections","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/collections?post=1957"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}