I have been trying to implement a scroll-to-top button. Searching online I found this piece of code:
$('html, body').animate({scrollTop:0}, 'slow');
I am confused, why would they try to scroll both html
and body
and then playing around with overflow: hidden
on body
tag, I noticed you can't have a scrollbar for both html
and body
. Then on MDN I found another way to achieve the same thing as:
window.scroll({
top: 0,
left: 0,
behavior: 'smooth'
});
As we know window
is the global object, which obviously can't be scrolled.
- Does
window.scroll
internally scroll thehtml
element or thebody
element? - Can
body
element be scrolled at all? I triedoverflow: hidden
onhtml
and thenoverflow: scroll
onbody
but don't see a scrollbar.
CodePudding user response:
window.scroll()
effectively scrolls the document.scrollingElement
* which is now defined as being the <html>
element, but used to be the <body>
one in some UAs and still in Quirks mode.
This document.scrollingElement
is a relatively recent addition and that's why you may still find old code that dealt with both <body>
and <html>
to honor all browsers.
*Per specs it scrolls the "viewport" but that boils down to the same since the step 12 of the scroll
algorithm passes the " document’s root element as the associated element" to the actual "Perform a scroll" operation.
const frameContent = `<html>
<body><h1 style='height:300vh'>%s Mode</h1>
<script>
scroll(0, 200);
parent.postMessage({
compatMode: document.compatMode,
html: document.documentElement.scrollTop,
body: document.body.scrollTop,
}, '*')
<\/script>`;
document.querySelectorAll("iframe").forEach((el, i) => {
el.src = `data:text/html,` encodeURIComponent(
(i ? "<!DOCTYPE html>" : "") // set the first frame to Quirk mode
frameContent.replace("%s", i ? "Default" : "Quirk")
);
});
onmessage = ({data}) => console.log(data)
<iframe></iframe>
<iframe></iframe>
CodePudding user response:
- Does window.scroll internally scroll the html element or the body element?
Neither. It scrolls the viewport. The precise description of the scrolling is given in the CSSOM view spec.
- Can body element be scrolled at all? I tried overflow: hidden on html and then overflow: visible on body but don't see a scrollbar.
Yes. but overflow: visible
won't display a scrollbar. You need overflow: scroll
or overflow: auto
. And to make it scroll, the content must overflow the body. e.g.
html {
overflow: scroll;
width: 630px;
}
body {
height: 80px;
overflow: auto;
}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Here you can see two vertical scrollbars. The one on the viewport, forced to display by the overflow: scroll
on the html element, and the one on body because the content overflows it, and it has overflow: auto
.
We can make both scrollbars scrollable if both are overflowed by their contents.
html {
overflow: auto;
border:2px solid red;
}
body {
height: 110vh; /* overflows the viewport - but note:
as you can see from the red and
blue borders, not the html emlement. */
overflow: auto;
border:2px solid blue;
}
p {
height: 130vh; /* overflows the body element */
}
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.<p>