Understanding Dynamic Elements
by kirupa (https://www.kirupa.com/me/index.htm) | filed under JavaScript 101 (https://www.kirupa.com/javascript/learn_javascript.htm)
When we write HTML, we have our source document where we specify the various elements that make up our web page. When our browsers read our HTML document, they create their own interpretation of what they encounter from our source HTML. This interpretation is something known as the DOM or Document Object Model.
Now, it is natural to expect that the source HTML and its interpretation by the browser into the DOM are identical:
[Image: ] (https://www.kirupa.com/html5/images/dom_equal_200.png)
For a lot of simple documents, this expectation is totally true. The DOM based on the source HTML will match the DOM created by the browser when reading the source HTML. As what we build goes slightly beyond simple, the two DOMs will start to look different:
[Image: ] (https://www.kirupa.com/html5/images/dom_no_equal_200.png)
What is going on? What can cause our source DOM and runtime DOM to get so out-of-sync? The answer lies in a mysterious creature known as the dynamic element and the role it plays in our everyday lives. Let's learn more about it!
Onwards!
Dynamic Elements FTW!
Dynamic elements are regular old HTML elements that get created by the browser and only exist as part of the runtime DOM. There are a handful of ways a dynamic element can find itself into our pages. Let's quickly look at what those handful of ways might be.
Creating Elements using JavaScript
As with many mysterious happenings in our web pages, you can't go wrong with pointing the finger at JavaScript. One of the most common reasons why dynamic elements exist is because they getcreated by JavaScript (https://www.kirupa.com/html5/creating_dom_elements_and_other_stuff.htm). Take a look at the following example:
Hello...
When we put all this in a HTML document and preview it in our browser, what we'll see will look as follows:
[Image: ] (https://www.kirupa.com/html5/images/dynamic_elements_created.png)
We'll see two yellow blocks with the words Hello and What's up? appears. One of these blocks is made up entirely of dynamic elements. The way to figure out which elements are dynamic and which ones have always existed in our source DOM involves comparing the source HTML with the runtime DOM our browsers generate.
To view the source HTML, we can look at our code editor for the page we created. Another easy way is by right clicking anywhere in our web page in our browser and selecting View Source. In both approaches, we will see the full source contents of our document appear:
[Image: ] (source_view.png)
To view the runtime DOM, you need to bring up the Developer Tools and go into Element inspection mode. In Chrome, we can click on the Elements tab to see the runtime DOM:
[Image: ] (https://www.kirupa.com/html5/images/runtime_dom_inspected.png)
Notice that our source DOM only contains the elements that correspond to Hello. The runtime DOM contains the elements for both the Hello and the supposedly dynamic What's up? text. We can definitively see the dynamicness of the What's up? text when we look at our JavaScript:
let textElement = document.createElement("p");
textElement.textContent = "What's up?";
let parentElement = document.createElement("div")
parentElement.appendChild(textElement);
document.body.appendChild(parentElement);
Notice that we are using createElement, appendChild, and other related DOM APIs (https://www.kirupa.com/html5/creating_dom_elements_and_other_stuff.htm) to create the div and p elements that allow the What's up? text to actually appear. Because we are talking about JavaScript, the only time it can do its thing is when the page (and associated scripts) are loaded at runtime by the browser.
Even if you don't set out to write JavaScript that ends up creating elements, if you take a dependency on a 3rd party library like React or Vue, you won't really have a choice. Behind the scenes, dynamic elements are being created on a large scale!
CSS and Pseudo-Elements
At one point, CSS was just about styling whatever content was on our page. With the latest versions of CSS that all browsers support, we now have the ability to create dynamic elements (formally known as pseudo-elements in the CSS world) directly from a style selector. Take a look at the following example:
Hello...
If we take all of this markup, plop it into a HTML document, and preview this document in our browser, this is what we will see:
[Image: ] (https://www.kirupa.com/html5/images/smiley_pseudo.png)
Notice what is going on here. Our p element just tells the browser to display the word Hello:
Hello
Where did the smiley emoji come from? The answer to that lies in the following CSS:
p {
font-size: 3em;
margin: 20px;
}
p::after {
content: " 😀";
}
The p::after selector tells our browser to create an element after every occurrence of the p tag with the content we specify. In this case, the content we specified is the smiley emoji. This is yet one more case where the source DOM won't know much about what is going on. It isn't until the page is read by the browser and the style selectors get run where any dynamic elements get created and represented in the runtime DOM.
Browser Rendered HTML Elements
The last area where dynamic elements get created has to do with our browser itself. HTML is a very forgiving language. You can often skip certain important tags, you can sometimes even forget a closing tag, and do all sorts of shenanigans. Our browsers will do their best to guess at our intention and fill-in any missing elements themselves. Take a look at the following example:
Hello...
Pay attention to our HTML very carefully. Notice something missing? Here is a hint: It starts with a b and ends in ody. We forgot to specify our body element! Despite this seemingly major omission, our page will load and display just fine. If we inspect our runtime DOM via the developer tools, notice that our body element is defined for us:
[Image: ] (https://www.kirupa.com/html5/images/body_element_is_here.png)
This is thanks to our browser dynamically generating this missing element and doing a pretty good job placing it where it makes the most sense. This missing body element is just one of many situations where our browser will try to help fix a mistake we may have accidentally made. Tying it to the theme of this article, these missing elements our browser creates automatically are also dynamic elements that only exist in the runtime DOM but not in our original HTML source.
Conclusion
The dynamic nature of our web pages and apps makes the source HTML we write seem very incomplete. When the browser goes through what we specified, depending on what code we have, what selectors we have, and what elements our browser decides to generate, our runtime DOM is almost always going to differ from the source DOM we started off with in our source HTML. Now, one question is whether the View Source command all browsers have to display the source HTML is even relevant in today's world? Being able to see the source DOM has its uses, but given my default inclination to use the developer tools for all debugging/inspecting tasks, I probably wouldn't even notice if View Source was removed at some point 😈