nonopolarity
nonopolarity

Reputation: 151214

It seems <html> element is like a pseudo window element or view container element?

If any webpage has 3000px tall of content, I would have expected both

document.body.offsetHeight
document.documentElement.offsetHeight

to be both 3000px. Note that document.documentElement is exactly the same as the <html> element:

document.documentElement === document.querySelector("html")   // true

However, document.documentElement.offsetHeight is not 3000px. It is merely 800px or 600px (as tested on the current StackOverflow page), and it just depends on how tall the window of the content area (or viewport) roughly is.

In fact, document.documentElement.scrollTop changes when the webpage is scrolled up. document.body.scrollTop remains 0 all the time.

This is exactly the same behavior as if there is a container div of 200px × 200px, with overflow set to auto or scroll, and then the content div inside the container div is 2000px × 2000px. In such case, the container div has a small clientHeight or offsetHeight (about 200px) and scrollTop changes when the content is scrolled up and down.

Is this how it is originally designed to be? Maybe for many years I thought <html> and <body> elements have almost the same: the content displayed to user is the same (<head> isn't displayed) and their height and width are the same and it was a misconception? It feels like the design principle is that <html> is like a view container or a pseudo window.

Even the CSS participated in this:

getComputedStyle(document.documentElement)["height"]  // 600px or small number
getComputedStyle(document.body)["height"]             // 3000px

But perhaps one strange behavior is, if I add a scroll event listener, I have to add it to document or window but not document.documentElement:

document.documentElement.addEventListener("scroll", ...  // won't work 

And it is different if it is the case for the 200px × 200px container case above. The event handler would be added to this 200px × 200px container.

Example involving document.documentElement.scrollTop and document.documentElement.scrollHeight (when everything is scrolled up, then the background becomes yellow):

document.addEventListener("scroll", ev => {
  // console.log(ev);
  document.body.style.background = document.documentElement.scrollTop + document.documentElement.clientHeight === document.documentElement.scrollHeight ? "yellow" : "white"; 
})
<div>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Dui sapien eget mi proin sed libero enim. Vel risus commodo viverra maecenas accumsan lacus vel. Magnis dis parturient montes nascetur. Amet nisl suscipit adipiscing bibendum est ultricies integer quis auctor. Nullam non nisi est sit amet facilisis magna etiam. Porttitor leo a diam sollicitudin tempor id eu. Turpis egestas sed tempus urna et pharetra pharetra massa massa. Phasellus egestas tellus rutrum tellus pellentesque. Arcu odio ut sem nulla pharetra diam. Felis imperdiet proin fermentum leo vel orci. Id donec ultrices tincidunt arcu non. Egestas pretium aenean pharetra magna ac placerat. Amet risus nullam eget felis.

  Laoreet id donec ultrices tincidunt arcu non sodales neque. Dolor magna eget est lorem ipsum dolor. Interdum consectetur libero id faucibus nisl. Amet purus gravida quis blandit turpis cursus in hac habitasse. Ultrices gravida dictum fusce ut placerat. Tortor consequat id porta nibh venenatis cras sed felis. Sagittis eu volutpat odio facilisis mauris sit. Massa placerat duis ultricies lacus sed turpis tincidunt id aliquet. Vel quam elementum pulvinar etiam non quam lacus. Blandit turpis cursus in hac habitasse platea dictumst.

  Amet justo donec enim diam vulputate. Cursus mattis molestie a iaculis at. Massa massa ultricies mi quis hendrerit dolor. Est ultricies integer quis auctor elit. Id venenatis a condimentum vitae. Amet mauris commodo quis imperdiet. Pretium viverra suspendisse potenti nullam ac. Ultrices dui sapien eget mi. Mattis molestie a iaculis at erat pellentesque adipiscing. Commodo quis imperdiet massa tincidunt. Arcu non sodales neque sodales. Nibh tortor id aliquet lectus proin. Nam at lectus urna duis convallis convallis. Faucibus nisl tincidunt eget nullam non nisi.
</div>

I got very different results for the following

console.log(document.body.offsetHeight);
console.log(document.documentElement.offsetHeight);

inside the current StackOverflow webpage (using Google Chrome's developer console). But if I create a very long plain HTML file, and do the above two lines in its <script> or in developer's console, I got similar numbers for <body> and <html>. So I am confused why a plain page and StackOverflow behave differently. It seems <html> can be used as a pseudo window or not as one.

But inside the long plain HTML page, if I do:

console.log(document.body.clientHeight);
console.log(document.documentElement.clientHeight); 

I was able to get 2400px for the and 680px for <html>. So it looks like it is still using <html> as a pseudo window or view container. But I thought clientHeight and offsetHeight are very close but just the scrollbar size is included in offsetHeight. I wonder why they are so different in this case.

Example:

console.log(document.body.clientHeight);
console.log(document.documentElement.clientHeight); 
body { font-size: 36px; }
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. At quis risus sed vulputate odio ut enim blandit. Dolor sed viverra ipsum nunc aliquet bibendum enim facilisis gravida. Sit amet purus gravida quis blandit. Et ultrices neque ornare aenean euismod elementum. Varius duis at consectetur lorem donec massa sapien faucibus et. In iaculis nunc sed augue. Platea dictumst quisque sagittis purus sit amet. Tortor at risus viverra adipiscing at in tellus. Mauris commodo quis imperdiet massa tincidunt nunc pulvinar sapien. Rhoncus est pellentesque elit ullamcorper dignissim cras. Porttitor lacus luctus accumsan tortor posuere. Velit sed ullamcorper morbi tincidunt ornare massa eget egestas. Sed nisi lacus sed viverra tellus. Et ligula ullamcorper malesuada proin libero. Velit scelerisque in dictum non consectetur a erat nam. Non tellus orci ac auctor augue mauris augue neque gravida. Proin libero nunc consequat interdum varius sit. Hac habitasse platea dictumst quisque sagittis purus sit amet.

Dolor morbi non arcu risus. Elit duis tristique sollicitudin nibh sit amet commodo nulla. Tincidunt praesent semper feugiat nibh sed pulvinar. Amet consectetur adipiscing elit pellentesque habitant morbi tristique. Feugiat scelerisque varius morbi enim nunc faucibus a pellentesque sit. Lectus mauris ultrices eros in cursus turpis massa tincidunt dui. Sit amet nisl suscipit adipiscing. Amet nulla facilisi morbi tempus iaculis. Suspendisse sed nisi lacus sed viverra. Nullam ac tortor vitae purus. Risus quis varius quam quisque id diam vel quam. Enim ut sem viverra aliquet eget. Ridiculus mus mauris vitae ultricies leo integer malesuada nunc vel. Dictum varius duis at consectetur lorem donec massa. Eu feugiat pretium nibh ipsum consequat nisl vel. Amet risus nullam eget felis eget nunc lobortis. Egestas purus viverra accumsan in nisl.

Dignissim diam quis enim lobortis. Eget duis at tellus at urna condimentum mattis pellentesque. Eu nisl nunc mi ipsum faucibus vitae aliquet nec. Lectus urna duis convallis convallis tellus id interdum velit laoreet. Velit ut tortor pretium viverra suspendisse. Euismod in pellentesque massa placerat duis ultricies lacus sed turpis. Et sollicitudin ac orci phasellus egestas tellus rutrum tellus pellentesque. Id faucibus nisl tincidunt eget nullam non nisi est. Ut venenatis tellus in metus vulputate. Lectus proin nibh nisl condimentum. Bibendum at varius vel pharetra vel. Quam vulputate dignissim suspendisse in. Ut etiam sit amet nisl purus in mollis nunc. Blandit volutpat maecenas volutpat blandit aliquam etiam erat velit scelerisque.

Ac ut consequat semper viverra nam libero justo. Lacus vel facilisis volutpat est velit egestas. Amet aliquam id diam maecenas ultricies. Enim tortor at auctor urna. Magna etiam tempor orci eu. Sollicitudin tempor id eu nisl nunc mi ipsum. Etiam tempor orci eu lobortis elementum nibh tellus. Velit ut tortor pretium viverra suspendisse potenti nullam ac tortor. Nulla facilisi cras fermentum odio eu feugiat pretium nibh. Eu tincidunt tortor aliquam nulla facilisi cras fermentum. Proin libero nunc consequat interdum varius sit amet mattis. Semper risus in hendrerit gravida rutrum quisque non tellus orci. Risus nullam eget felis eget nunc lobortis.

Risus sed vulputate odio ut enim blandit volutpat maecenas volutpat. In nulla posuere sollicitudin aliquam. Sagittis nisl rhoncus mattis rhoncus urna neque viverra. Sit amet justo donec enim diam vulputate. Ut faucibus pulvinar elementum integer. Interdum posuere lorem ipsum dolor sit amet consectetur adipiscing elit. A condimentum vitae sapien pellentesque habitant morbi tristique. Vel fringilla est ullamcorper eget nulla facilisi. Vitae purus faucibus ornare suspendisse sed nisi lacus sed viverra. Aenean vel elit scelerisque mauris pellentesque pulvinar pellentesque. Ultricies integer quis auctor elit sed vulputate mi. Euismod quis viverra nibh cras pulvinar mattis. Sapien pellentesque habitant morbi tristique senectus et netus et malesuada. Mi tempus imperdiet nulla malesuada pellentesque elit eget.

Tincidunt augue interdum velit euismod in pellentesque massa placerat duis. Nam libero justo laoreet sit amet. Feugiat pretium nibh ipsum consequat nisl vel pretium lectus. Facilisi etiam dignissim diam quis enim. Augue lacus viverra vitae congue eu. Velit scelerisque in dictum non consectetur a erat nam. Amet purus gravida quis blandit turpis cursus in. Tortor pretium viverra suspendisse potenti nullam ac. Dolor sit amet consectetur adipiscing elit ut. Proin sed libero enim sed faucibus turpis in eu. Amet nulla facilisi morbi tempus iaculis urna id volutpat. Ut pharetra sit amet aliquam id diam maecenas ultricies mi. At in tellus integer feugiat. Vestibulum lectus mauris ultrices eros in cursus turpis massa. Dui nunc mattis enim ut tellus. Elit duis tristique sollicitudin nibh. Ac odio tempor orci dapibus ultrices in. Netus et malesuada fames ac turpis egestas sed. Quam lacus suspendisse faucibus interdum posuere lorem ipsum. A lacus vestibulum sed arcu non odio euismod lacinia.
</div>

One thing we also need to be careful about, is as stated in JavaScript Definitive Guide 6th Ed p.395 and p.903 and on the specs, clientWidth and clientHeight behaves differently if it is on the <html> element, which is to give the viewport's width and height excluding any scrollbar. So when the page is studied, this needs to be kept in mind.

Likewise, there is even such an exception on scrollTop on <html>. It is the scrollY of window in such a case..

I think one conclusion so far is, it seems <html> is somehow treated as a pseudo window or viewing area programmatically, as how its properties are specified in the specs.

Upvotes: 1

Views: 169

Answers (1)

Kaiido
Kaiido

Reputation: 137131

First, if here in Stack Overflow's page you get the .offsetHeight and getComputedStyle()['height'] to be the size of the viewport, it is because there is a rule stating html { height: 100%; }.

Without this rule, you'd have it the same size as the body:

console.log( "height:auto" );
console.log( "offsetHeight", document.documentElement.offsetHeight );
document.documentElement.classList.add( "SO" );
console.log( "height:100%" );
console.log( "offsetHeight", document.documentElement.offsetHeight ); 
body {
  height: 1000vh;
}
html.SO {
  height: 100%;
}

Now for the scroll related values, the document.documentElement element is the de-facto document.scrollingElement in a normal web-page:

console.log( document.scrollingElement === document.documentElement );

and it is the document.body in quirks mode.

Given this special status, the scroll related values of the scrollingElement actually return the root node's ones, which has its containing block's dimensions set to the viewport's dimensions in normal web pages.

Upvotes: 2

Related Questions