7

Rendering Elements After The HEAD Tag In JavaScript

 1 year ago
source link: https://www.bennadel.com/blog/4411-rendering-elements-after-the-head-tag-in-javascript.htm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Rendering Elements After The HEAD Tag In JavaScript

By Ben Nadel on February 20, 2023

The other day, when I was exploring the progress bar in Hotwire, I noticed that the <div> implementing the progress bar was injected into the DOM (Document Object Model) after the <head> tag and before the <body> tag. I didn't know that it was possible to render elements outside of the Body tag. And, in fact, statically rendered elements outside of the Body will be "moved" into the Body (by the browser) as the HTML is parsed. However, it turns out that you can render elements between the Head and Body tags at runtime using JavaScript.

Run this demo in my JavaScript Demos project on GitHub.

View this code in my JavaScript Demos project on GitHub.

I assume that the Hotwire framework is making this choice because it swaps out the entire <body> tag when a new page is loaded. As such, any elements contained within the <body> tag will be implicitly removed. Which means, if the progress bar is outside the Body tag, the progress bar can be persisted even as the Body tag is being replaced.

That's a cool use-case; but, when I saw this, my immediate thoughts went to stacking context. Stacking context is the key to understanding z-index layering. If you've ever seen a developer using a CSS property like:

z-index: 999999999 ;

... it's because they don't understand how z-index works; and, they're just throwing numbers at the wall to see what sticks. It's a futile attempt to break free from a "stacking context" that is locking-down layering within a branch of the DOM.

The main rendered branch of the DOM is the <body> element. Which means, if we can create a "stacking context" on the Body tag itself, anything outside of the Body, will be in a different stacking context and can freely stack above or below the Body layer.

To demonstrate this, I've created a page with two <div> elements using z-index: 2. They are both defined in between the Head and Body tags; however, one of them is dynamically injecting itself after the <head> using JavaScript:

As you can see, the "box" element is our control layer and has a high z-index. Each of my other elements use a z-index of 2. Normally, this would place both elements below the box from a stacking perspective. However, when we run this page, we get the following output:

The dynamically injected element is stacked above the box while the static element is stacked below the box.

As you can see, the browser moved the statically defined element into the Body tag as it parsed the HTML, which is why it is layered below the "box". However, the dynamically defined element (which uses JavaScript to inject itself after the Head tag), is allowed to remain after the <head>. And, because it is rendered outside of the <body> tag, it is stacked above the "box" despite having a much lower z-index.

Accessibility Concerns

I don't know that much about accessibility. But, I have to assume that content rendered outside of the <body> has all kinds of accessibility issues. As such, it's probably a bad idea to use this technique to render consumable "content". However, for something like a progress bar that is nothing more than a visual indicator (ala the Hotwire framework), this seems like a rather clever approach.

Want to use code from this post? Check out the license.

Enjoyed This Post? ❤️ Share the Love With Your Friends! ❤️

Tweet This Fascinating post by @BenNadel - Rendering Elements After The HEAD Tag In JavaScript https://www.bennadel.com/go/4411

Reader Comments

What has two thumbs and hopes you leave a comment? This Guy! (Ben Nadel).

Post A Comment — ❤️ I'd Love To Hear From You! ❤️

Name:

Email:

Website:

Comment:
NEW: Some basic markdown formatting is now supported: bold, italic, blockquotes, lists, fenced code-blocks. Read more about markdown syntax »
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Subscribe to comments.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK