My element has a CSS class that defines what the height of it should be.
.very-long-container {
height: 50px;
}
<div class="very-long-container">...</div>
I want to know the original height of that element, so not what is defined with CSS.
Well, my way of getting the height is to reset the CSS first, get the original height and then set the height with CSS again. Like this:
document.querySelector('.very-long-container').style.height = 'inherit';
console.log(document.querySelector('.very-long-container').offsetHeight);
document.querySelector('.very-long-container').style.height = '50px';
Since this is not the best practice, I am sure that there are better answers.
The container is 50px and will always be that if you tell it. When you remove the 50px from the CSS it will take the height of the children inside of it.
So one way of know what the actual height would be whenever there is no fixed height set is to either have another container inside of the container or to sum the height of all children inside of the container.
The former is the easiest to work out. If a child container does not have a fixed height, it will automatically take the height of the children inside of it, despite the outer container having a fixed height.
The example below uses the aforementioned technique. Reading the offsetHeight of the inner container. As a bonus it uses a ResizeObserver to update the height whenever the size of the inner container changes.
const innerContainer = document.querySelector('.inner-container');
let height = innerContainer.offsetHeight;
const resizeObserver = new ResizeObserver(entries => {
for (const { target } of entries) {
height = target.offsetHeight;
console.log(height);
}
});
resizeObserver.observe(innerContainer);
.very-long-container {
height: 50px;
overflow: hidden;
}
<div class="very-long-container">
<div class="inner-container">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam congue efficitur purus vel posuere. Nam eget tincidunt dolor, eu tempor neque. Aliquam ac ex urna. Ut scelerisque urna purus, tincidunt bibendum massa accumsan id. Mauris vitae cursus mi.
Phasellus imperdiet vel metus et ornare. Donec nulla justo, convallis sed lacus at, dapibus rhoncus neque. Cras velit erat, lacinia eu lectus lobortis, rhoncus congue ex. Curabitur lacus diam, dignissim at tortor ac, suscipit venenatis tortor. Fusce
tempus consectetur dui, vel placerat purus luctus nec. Morbi elementum, mi lacinia rhoncus vehicula, dolor dolor iaculis augue, id feugiat arcu tortor sed lectus. Quisque lacus justo, luctus sit amet finibus quis, pretium sed ex.
</p>
<p>
Morbi luctus neque non nunc placerat varius. Sed cursus scelerisque mi id interdum. Sed sodales orci ut laoreet imperdiet. Duis pretium erat ut libero consectetur ultrices. Aenean suscipit ultricies diam at pretium. Fusce pharetra lectus at lectus ornare,
sit amet lobortis libero lacinia. Quisque odio orci, ornare sed molestie non, fermentum at enim. Nam ut tortor enim. Nulla facilisi. Maecenas vehicula vitae felis ut mollis. Nam varius elementum felis, condimentum hendrerit velit elementum eu. Praesent
laoreet, turpis vel condimentum auctor, nisi erat viverra purus, sed gravida odio nulla nec urna.
</p>
<p>
Morbi sed enim ligula. Fusce vitae feugiat nunc. Sed vel velit orci. Nunc ut euismod ipsum. Cras sed velit nec lectus scelerisque sagittis. Fusce non nunc leo. Donec viverra eu felis sed molestie. Proin ut molestie libero, ut ultricies purus. Nullam dapibus
felis non vestibulum aliquam. Mauris quam mi, dictum eu nisi vitae, malesuada ultricies turpis. Donec vitae dolor leo. Nulla at dui eget eros molestie congue. Etiam imperdiet lobortis feugiat.
</p>
<p>
Maecenas enim magna, convallis vitae scelerisque at, lobortis vitae elit. Cras interdum ipsum non purus feugiat rhoncus. Fusce eu elit porttitor, aliquet libero at, dapibus massa. Suspendisse dignissim varius mauris, sed ullamcorper mauris interdum quis.
Proin viverra purus massa, in finibus magna faucibus ut. Nulla malesuada ipsum vel maximus vestibulum. Vestibulum molestie in dui fringilla interdum. Donec dignissim sapien nisl. Suspendisse aliquam elit turpis, at euismod mauris consectetur vel.
</p>
<p>
Suspendisse fermentum urna a arcu dignissim tincidunt. Nulla pellentesque orci vitae vulputate rutrum. Vestibulum interdum faucibus lectus vel vehicula. Suspendisse egestas dolor sit amet justo vehicula sodales. Integer fringilla eget erat id rhoncus.
Aenean luctus purus ut libero volutpat, viverra lobortis dui maximus. Integer sit amet aliquet nulla. In suscipit id orci sed tincidunt. Suspendisse pharetra suscipit tempus. Cras mattis a nibh eu porttitor. Donec nec iaculis metus. Pellentesque
molestie diam eu eleifend cursus. Suspendisse tincidunt, lorem quis pulvinar viverra, metus felis imperdiet nisi, ut dignissim velit urna nec odio. Quisque pulvinar turpis non ipsum mattis, a iaculis ipsum pellentesque. Vestibulum finibus sed sapien
quis faucibus. Vivamus tristique, neque id finibus ultrices, sapien elit consequat odio, placerat commodo magna odio id velit.
</p>
</div>
</div>
Related
There are lot of similar questions to this.I have a react project in which I want to disable the parent/body scrolling when a modal/popup is in hover or focused state. I needed the parent scroll to be visible only the scrolling should be disabled when the modal is hovered or focused. I tried overflow:hidden and position:fixed but it makes the parent scroll disappear. Is there any way we can achieve this. I am new to UI , any help would be appreciated.
body {
position: fixed;
max-height: 100vh;
overflow-y: scroll;
}
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tempor congue leo, ullamcorper gravida dui. Integer dignissim euismod facilisis. Etiam eget accumsan justo. Ut vitae eros semper, pulvinar tortor eget, viverra metus. Proin eleifend eros
tortor, vel lobortis sem consequat quis. Phasellus euismod fermentum condimentum. Nulla id vehicula dolor, id rutrum metus. Curabitur tempor posuere enim, et accumsan lectus malesuada vitae. Morbi ultrices fringilla lacus vel ultricies. Etiam ut urna
massa. Morbi porttitor quam eget nisi volutpat, id tempor justo imperdiet. Nullam maximus venenatis turpis, a semper ligula placerat nec. Aliquam hendrerit magna a laoreet elementum. Duis efficitur, lacus sed lacinia porta, nibh ante eleifend lacus, et
viverra mi elit eget nulla. Fusce ultrices faucibus orci vel fermentum. Donec a consectetur turpis, id ultricies risus. Vestibulum iaculis porttitor justo, sit amet pellentesque est vulputate ac. Suspendisse nisi ex, gravida dapibus ipsum vitae, pharetra
efficitur tellus. Vivamus varius elementum euismod. Nunc elit diam, laoreet vel finibus at, porttitor vel est. Maecenas dignissim nibh eu nibh pellentesque ornare. Curabitur feugiat iaculis mi, ullamcorper hendrerit ex scelerisque ac. Donec blandit ipsum
sit amet nibh elementum, vitae efficitur nisi maximus. Curabitur sodales, elit a bibendum tempor, elit sem pellentesque metus, sit amet tempor diam nulla id sapien. In aliquam magna at turpis semper, et consectetur lorem egestas. Nunc ornare erat eros,
quis efficitur nibh tincidunt ac. Nunc imperdiet lectus id libero semper cursus eu vel turpis. Proin tincidunt sollicitudin metus consequat vehicula. Etiam sed nunc tincidunt, imperdiet mi eget, rutrum enim. Aenean scelerisque imperdiet tortor id sodales.
Aenean faucibus bibendum pharetra. Etiam sagittis odio nec risus malesuada egestas. Cras vel lorem a neque efficitur scelerisque. Pellentesque ut lorem id dolor varius dictum eget non metus. Nunc consectetur lectus sit amet nulla sollicitudin, eu tincidunt
neque cursus. Nullam in enim ullamcorper, ultrices velit non, suscipit lorem. Nunc eleifend urna non fermentum tincidunt. Curabitur fermentum dui eros, consectetur feugiat risus aliquam nec. Sed efficitur nec nulla eu porta. Suspendisse ipsum massa, elementum
vel blandit vel, hendrerit at nibh. Etiam tempus massa non pellentesque hendrerit. In commodo nisl quam, ut aliquet ipsum varius a. Donec magna justo, luctus eu congue tempus, feugiat ut est. Proin suscipit eu lorem vel imperdiet. Morbi suscipit nisi
sem, finibus pulvinar magna scelerisque non. Proin molestie, nisl non tincidunt suscipit, mauris nunc commodo diam, et lacinia diam libero sit amet felis. Praesent vestibulum risus id erat consequat, ac maximus mauris pulvinar. Etiam tempus interdum est
sed aliquet. In hac habitasse platea dictumst. Curabitur maximus sodales tempus. Suspendisse dapibus vestibulum blandit. Ut mollis interdum fringilla. Maecenas neque purus, rhoncus nec tortor at, elementum dictum sem. Aenean sit amet elit facilisis, euismod
felis non, elementum tortor. Mauris eget aliquam mauris, at volutpat mi. Donec in ligula ac lectus rhoncus pulvinar. Suspendisse a nulla id mi convallis congue quis vitae massa.
Found a more precise solution for this usecase. Simple adding below property in overlay class
overscroll-behavior: contain
I currently have a div with a list of text and a button that adds more lines of text. Once the lines of text reach the bottom of the screen the scrollbar appears. I would like the scrollbar the appear transparent and on top of the div rather than fully opaque and next to the div how it is currently. Is there any way to do this?
I used overflow:overlay; to display scrollbar over content and background-color on the thumb and track to make them 25% opaque. Please see snippet below :
div{
height:100px;
background-color:lightblue;
overflow:overlay;
}
/* ===== Scrollbar CSS ===== */
/* Firefox */
* {
scrollbar-width: auto;
scrollbar-color: #00000025 #ffffff25;
}
/* Chrome, Edge, and Safari */
*::-webkit-scrollbar {
width: 16px;
}
*::-webkit-scrollbar-track {
background: #ffffff25;
}
*::-webkit-scrollbar-thumb {
background-color: #00000025;
border-radius: 10px;
border: 3px none #00000025;
}
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum luctus scelerisque facilisis. Etiam vestibulum neque at ornare lacinia. Phasellus malesuada massa vel dapibus volutpat. Donec elit metus, mollis id egestas vel, mattis et felis. Duis rutrum diam eu lacus molestie mollis. Phasellus interdum imperdiet vehicula. Morbi eget ex massa.
Curabitur interdum semper mauris non efficitur. Ut eros ipsum, blandit sit amet hendrerit sed, tincidunt nec est. Duis finibus posuere orci sit amet semper. Ut quis ligula nec purus elementum accumsan quis id felis. Sed eget imperdiet dui. Suspendisse faucibus porttitor massa. Proin auctor, libero ut pharetra ullamcorper, arcu enim lobortis tellus, in mollis mi turpis vitae nibh. Pellentesque eget neque pharetra, ornare diam quis, vehicula risus. Phasellus pellentesque facilisis enim, vitae elementum augue. Phasellus ac vulputate nunc. Morbi non ante gravida, mattis nisi eu, ullamcorper sem. Nullam egestas ligula ut lectus dapibus vehicula. In in erat viverra, sagittis odio a, venenatis erat. Nunc ut nunc scelerisque, egestas sapien sed, venenatis lorem. Vivamus fringilla nunc leo, in dictum tortor vehicula vitae.
Donec eleifend est in felis molestie convallis. Etiam dolor ligula, lobortis eu molestie feugiat, aliquam eget ligula. Quisque tempor ornare enim, sed varius mi vestibulum sit amet. In at vestibulum ligula. Vivamus pretium non purus vel scelerisque. Pellentesque a mauris sit amet orci lobortis pellentesque. In purus nulla, maximus non sapien vitae, rhoncus tristique arcu. In placerat dui vel iaculis commodo. Nullam malesuada suscipit nulla, at scelerisque tortor vulputate at. In a diam at libero cursus bibendum in vitae libero. In tortor magna, ornare nec massa vitae, sagittis tincidunt turpis.
Proin malesuada in lectus vitae suscipit. Sed nibh risus, accumsan vel enim vel, mattis porta augue. Aliquam et lacinia neque. Etiam pellentesque tempor augue eget ullamcorper. Aenean dictum efficitur dolor sed ultrices. Donec vitae euismod odio. Nam quis posuere ante. Fusce quis sagittis nulla, sit amet gravida urna. Nulla facilisi. Vivamus id auctor mi. Curabitur pellentesque risus et tortor viverra, vitae pretium ex fringilla. Mauris efficitur maximus lorem vitae hendrerit. Cras efficitur sollicitudin sapien sed dignissim. Duis fermentum imperdiet tincidunt. Praesent augue justo, elementum eu pharetra in, iaculis quis ipsum. Donec sit amet varius arcu, in dictum risus.
Ut ex urna, scelerisque quis augue a, viverra bibendum ligula. Aliquam iaculis dolor quis dolor finibus consectetur. Integer vehicula, turpis sed sollicitudin cursus, est justo posuere elit, non facilisis massa nulla id ligula. Duis tempus, sem vel congue scelerisque, augue mauris efficitur tortor, nec commodo magna sapien et eros. Donec ultrices dui mi, ut malesuada odio ornare a. Duis auctor, ex eu ultricies semper, leo diam consequat turpis, eu ornare felis velit rhoncus quam. Vestibulum lacinia ipsum nec ipsum laoreet faucibus. Mauris sed eros sem. Morbi a tellus quam. Nulla porttitor scelerisque massa eu efficitur. In metus libero, viverra fermentum accumsan et, tristique a ipsum. Proin lacinia tortor leo, facilisis volutpat ante elementum vel. Pellentesque sed ipsum ut sem lobortis mollis sed sit amet dolor. Pellentesque vulputate, justo id eleifend congue, felis enim consectetur nibh, id malesuada ipsum enim nec lectus.
</div>
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.
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.
element.scrollIntoView with behavior set to smooth is not working as I expect in Chrome. When it is used only on one element in a callstack, it works fine. But if it is used on multiple elements, only the last element will actually scroll.
This works fine in Firefox. Is there a workaround for this in Chrome?
const $ = (s) => document.querySelector(s)
const $$ = (s) => document.querySelectorAll(s)
const container = $(".container")
for (let i = 0; i < 2; i++) {
document.body.appendChild(container.cloneNode(true))
}
function scrollIntoView(behavior) {
for (const element of $$(".reveal")) {
element.scrollIntoView({
behavior,
block: "end"
})
}
}
$(".instant").addEventListener("click", () => scrollIntoView("instant"))
$(".smooth").addEventListener("click", () => scrollIntoView("smooth"))
$(".reset").addEventListener("click", () => {
for (const element of $$(".container")) {
element.scrollTo(0, 0)
}
})
.container {
max-height: calc(33vh - 12px);
overflow-y: auto;
}
.reveal {
color: red;
}
<button class="instant">
Instant
</button>
<button class="smooth">
Smooth
</button>
<button class="reset">
Reset
</button>
<div class="container">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed rhoncus elementum quam. Donec quis est volutpat, dapibus nisl at, consequat turpis. Quisque convallis nunc faucibus eros egestas, in faucibus neque fringilla. Duis aliquam, metus tempor dignissim
vestibulum, nulla elit lacinia lacus, vitae pulvinar augue diam et turpis. Aenean a velit sed elit dictum fringilla ut eu augue. Vestibulum hendrerit dolor mauris. Proin quis lacus a turpis posuere maximus. Sed lacus mauris, feugiat a iaculis porta,
lacinia vel eros. Integer tempor id tortor vitae fermentum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Etiam lobortis efficitur massa, eu elementum nulla eleifend ut. Quisque non erat iaculis, ornare erat non, interdum sapien. Suspendisse
sit amet interdum nisl, eu maximus libero. Fusce nisi nulla, iaculis eu est a, mattis tincidunt sem. Pellentesque non orci dapibus, dignissim ipsum a, finibus metus. Quisque placerat porta neque, eget finibus lectus tempus sed. Cras non gravida urna.
Morbi pretium mauris nec erat consectetur, vitae convallis lacus consectetur. Nam venenatis diam magna, sed venenatis nisl placerat viverra. Integer et mi pellentesque risus consectetur ultrices. Phasellus iaculis risus elementum, vulputate est sed,
consectetur diam. Phasellus lobortis felis purus, sit amet mattis elit pharetra ac. Nulla at viverra leo. Maecenas a condimentum magna. Maecenas porta tellus sit amet elit fermentum tincidunt. Donec ultricies blandit enim id mollis. Sed rutrum risus
sit amet posuere varius. Suspendisse suscipit maximus ligula eget egestas. Nullam lorem neque, viverra in sollicitudin ac, cursus nec purus. Aliquam placerat, arcu sit amet tincidunt consequat, ex est lacinia tellus, ac mattis nisl sapien at enim. Cras
lacinia libero eu eleifend sodales. Praesent a erat convallis, venenatis dui ut, semper sem. Vivamus tincidunt tempor neque, at congue lacus tincidunt et. Praesent consectetur, massa tristique laoreet sollicitudin, erat diam mattis nibh, nec consequat
mauris odio ut est. Integer pharetra arcu at finibus congue. Proin pellentesque fringilla blandit. Suspendisse egestas interdum nisl. Nulla facilisi. Quisque dapibus odio risus. Donec non orci dapibus risus pellentesque cursus vestibulum vel arcu. Proin
volutpat tellus sed elit auctor, sit amet tincidunt ante cursus. Donec faucibus sit amet libero sit amet lobortis. Pellentesque posuere nisl vitae pharetra vestibulum. Mauris et lobortis libero, vel facilisis metus. Duis eu venenatis dui. Fusce gravida
nibh odio, quis ullamcorper nibh rutrum sed. In dapibus, nulla non auctor egestas, nisi augue venenatis quam, et finibus lorem dui non turpis. Nullam arcu diam, mattis at erat ac, viverra lobortis felis. In in nisi magna. Ut ut ultrices velit, quis
vehicula libero. Proin dictum metus vel ante lobortis, in placerat magna ornare. Etiam vulputate metus felis, sed fringilla magna convallis vitae. Curabitur non pulvinar ante, eget molestie nibh. Quisque facilisis, diam sed dapibus blandit, ex urna
vulputate est, non auctor risus dui nec augue. Donec pretium laoreet est, tempor faucibus tortor laoreet ac.
<span class="reveal">Revealed!</span>
</div>
As per this draft at drafts.csswg.org, it is not possible to use the smooth function for scrolling multiple elements simultaneously;
When a user agent is to perform a scroll of a scrolling box box, to a given position position, an associated element element and optionally a scroll behavior behavior (which is "auto" if omitted), the following steps must be run:
Abort any ongoing smooth scroll for box.
If the user agent honors the scroll-behavior property and one of the following are true:
behavior is "auto" and element is not null and its computed value of the scroll-behavior property is smooth
behavior is smooth
...then perform a smooth scroll of box to position. Otherwise, perform an instant scroll of box to position.
Your options are:
Scroll the elements one by one using the native smooth function.
Use different API or library to animate the elements.
Functionally design the thing differently, so they don't need to scroll simultaneously.
So let's say I have a blue square and a compressed red-box:
So I want that, when I click on the square, the red-box readapts it's size to it's current content:
And when I click again on the square, I want the red box to return to it's original state:
And I want both movements to happen slowly, with the transition property.
So I have two problems: First, the transition is not working at any of the steps. Second, once I bring the box once to it's original state, I can't make it enlarge anymore.
Here's the code:
HTML:
<div id="red_box">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam commodo, ipsum non ultrices pulvinar, turpis nulla sollicitudin leo, vitae convallis orci velit sed ante. In sodales sed lorem in blandit. Proin ornare cursus tortor, at tincidunt libero. Nulla in ex in augue iaculis congue ut egestas odio. Morbi tristique varius lorem, id dictum magna convallis eget. Nulla sit amet massa eu tortor facilisis dapibus. Phasellus nec porttitor enim. Donec vitae pharetra nibh. Nam convallis arcu et rutrum fringilla.
Curabitur at mauris pharetra, ultrices tortor quis, congue tortor. In nec ornare eros. Morbi imperdiet luctus sem sit amet pellentesque. Maecenas ac accumsan sapien. Vivamus eu dui tristique, pharetra ex id, tincidunt est. Nulla viverra eu mi fringilla blandit. Ut sagittis quam nisl. In eu rutrum ex. Ut ac ante id nibh aliquam ultrices quis vel arcu. Donec molestie ipsum sapien, sed pellentesque lectus ornare sit amet. Maecenas vitae turpis arcu. Praesent ac faucibus sapien. Quisque ornare venenatis pulvinar. In felis metus, posuere non convallis id, commodo sed lorem.
Maecenas porta risus sed ipsum luctus mattis. Integer faucibus placerat justo, sed lobortis est gravida tincidunt. Aliquam ut aliquet sem, et sodales enim. Vivamus rhoncus sodales felis a fermentum. Phasellus pellentesque fringilla lorem ut lobortis. Maecenas erat urna, viverra et egestas consectetur, eleifend vel sem. Praesent fermentum vehicula porttitor. Duis faucibus gravida nulla non volutpat. Nam tincidunt ligula in nisi efficitur, a ultricies magna aliquam. Morbi commodo posuere egestas. Maecenas quis orci interdum velit elementum lacinia nec ac dolor. Nullam sodales magna at dui pharetra efficitur.
Nulla ultricies eros et ex tempus, eu faucibus orci dapibus. In ac sapien ornare, malesuada velit id, congue augue. Cras metus lectus, molestie id leo maximus, accumsan fermentum elit. Aliquam congue malesuada iaculis. Donec tempus enim quis tortor tristique finibus. Curabitur sed sapien quis felis venenatis porttitor quis sed dui. Phasellus in commodo orci. Vestibulum tempor purus vitae ultrices condimentum. Mauris mattis erat sed nunc suscipit tincidunt.
Quisque porttitor dolor vel faucibus molestie. Quisque sollicitudin accumsan ipsum, a ultrices lectus dignissim interdum. Integer vestibulum mauris vitae purus suscipit, ut rutrum ante vehicula. Sed sollicitudin lectus eu justo commodo aliquet. Etiam rhoncus tellus sed diam aliquam consequat. Aenean tristique, dolor et dignissim rhoncus, turpis urna euismod elit, ac commodo nulla purus id tellus. Aliquam suscipit consequat vestibulum.
Phasellus massa ex, pharetra nec augue eu, blandit volutpat ligula. Duis finibus nulla nunc, vitae ultrices nibh sollicitudin ac. Donec consectetur quam eu turpis dapibus, ut egestas arcu condimentum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque posuere tincidunt sem, at fermentum leo efficitur vitae. Maecenas mattis erat quis urna accumsan, vel elementum felis pellentesque. Etiam id pretium ex. Suspendisse arcu turpis, blandit rutrum mi eu, volutpat tincidunt nunc. Duis pretium, augue in faucibus convallis, turpis nulla tempus metus, at ornare dolor turpis ac elit. Ut dapibus diam vel sem aliquet aliquet id nec sapien. Sed dictum eu ligula quis dictum. Curabitur blandit neque eu nibh vestibulum, eget tincidunt nibh aliquam.
Nulla molestie ultricies sem, nec pharetra mi pharetra ac. Mauris aliquam vestibulum augue et convallis. Nunc rutrum quis felis at fermentum. Integer non mauris a augue finibus laoreet. Etiam dignissim tincidunt porttitor. Phasellus dignissim turpis eget accumsan hendrerit. Praesent nisl urna, semper nec luctus non, dignissim quis enim. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus elit lacus, rutrum et volutpat ac, hendrerit eu ante. Phasellus vitae erat ante. Aenean pulvinar libero eu magna auctor aliquet. Morbi facilisis, erat eu bibendum aliquet, dui augue mattis nisl, non bibendum lorem lorem sit amet odio. Vestibulum elit orci, posuere nec iaculis at, maximus quis libero.
</div>
<div id="square"></div>
CSS:
#red_box{
width:40%;
max-height:0px;
overflow:hidden;
background-color:white;
color:black;
border:5px double red;
position:relative;
left:55%;
transition:max-height 1s, overflow 1s;
display:inline-block;
}
#square{
float:left;
width:200px;
height:150px;
background-color:blue;
}
Javascript:
document.querySelector("#square").onclick = set_red_box;
function set_red_box(){
if(document.querySelector("#red_box").style.maxHeight == 0){
grow_red_box();
}
else{
diminish_red_box();
}
}
function grow_red_box(){
document.querySelector("#red_box").style.maxHeight = "5000000px";
document.querySelector("#red_box").style.overflow = "auto";
}
function diminish_red_box(){
document.querySelector("#red_box").style.maxHeight = "0";
document.querySelector("#red_box").style.overflow = "hidden";
}
And the JFiddle:
https://jsfiddle.net/rerr6ra8/2/
You can not use transitions this way because the height depends on the content in the box (auto). This is not supported by CSS transitions. However the max-height property is perfectly able to use with animations.
What you can do, is calculate the height with JavaScript and use that in with your code:
var redbox = document.getElementById('red_box');
var height = redbox.clientHeight;
redbox.style.maxHeight = "0px";
https://jsfiddle.net/rerr6ra8/7/
You can't animate an unknown height using transition, which means that height: auto doesn't work, you need to set height explicitly.
However, as you are using JS to change height, you can set the height to be equal to the scrollHeight, which is (mdn):
The Element.scrollHeight read-only attribute is a measurement of the
height of an element's content, including content not visible on the
screen due to overflow.
Fiddle
document.querySelector("#square").onclick = set_red_box;
var redBox = document.querySelector("#red_box");
var open = false; // redBox state used for toggle
function set_red_box() {
if (open) {
redBox.style.height = '0';
} else {
redBox.style.height = redBox.scrollHeight + 'px'; // scrollHeight is the full content height
}
open = !open;
}
CSS:
#red_box {
width:40%;
height: 0;
overflow:hidden;
background-color:white;
color:black;
border:5px double red;
position:relative;
left:55%;
transition: height 1s; /** change transition to height **//
display:inline-block;
}