Skip to content

Instantly share code, notes, and snippets.

@jjmu15
Created January 27, 2014 10:19
Show Gist options
  • Save jjmu15/8646226 to your computer and use it in GitHub Desktop.
Save jjmu15/8646226 to your computer and use it in GitHub Desktop.
check if element is in viewport - vanilla JS. Use by adding a “scroll” event listener to the window and then calling isInViewport().
// Determine if an element is in the visible viewport
function isInViewport(element) {
var rect = element.getBoundingClientRect();
var html = document.documentElement;
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || html.clientHeight) &&
rect.right <= (window.innerWidth || html.clientWidth)
);
}
The above function could be used by adding a “scroll” event listener to the window and then calling isInViewport().
@rrapstine
Copy link

rrapstine commented Jul 18, 2016

I spent 4 hours looking for a solution to this problem. Thank you!

@ilblog
Copy link

ilblog commented Sep 28, 2016

Thx

@QwertyZW
Copy link

Nice, be sure to account for anchored elements/z-indices if you're copy pasting this

@vonlooten
Copy link

Thank you!

@englishextra
Copy link

The drawback is that the whole element with its hight should be in viewport, not just some part of it.

@bresson
Copy link

bresson commented Mar 14, 2017

@englishextra: what if the element's height is longer than the viewport?

@englishextra
Copy link

englishextra commented Mar 27, 2017

@bresson make you browser window smaller in height and you target is an image that wil appear only part of it, the isInViewport will not trigger. But it will if the element is not hidden but has no height, say:

somewhere lower in your document:

<div id="disqus_thread"></div> //  it has no dynamic children appended yet
if (verge.inViewport(disqus_thread) // false
if (isInViewport(disqus_thread) // true

So the right name would be fitsIntoViewport

I recommend verge js lib which is small. But for now it wont say if something is in viewport if they are hidded with display none

@jsyzdek
Copy link

jsyzdek commented Apr 12, 2017

Works great- thanks!

@piotr-l
Copy link

piotr-l commented Feb 2, 2018

Thanks, it works perfectly.

@winrox
Copy link

winrox commented Feb 16, 2018

thanks so much!

@jorgeortega
Copy link

Thanks for this!

@tsimons
Copy link

tsimons commented May 3, 2018

Just wrote a similar version that only accounts for height, but returns true when any part of the element is in the viewport:

function isVisible (ele) {
  const { top, bottom } = ele.getBoundingClientRect();
  const vHeight = (window.innerHeight || document.documentElement.clientHeight);

  return (
    (top > 0 || bottom > 0) &&
    top < vHeight
  );
}

@abddayan
Copy link

thank you Jjmu15 and Tsimons. Your snippets each address different needs.

@cedrickvstheworld
Copy link

Just wrote a similar version that only accounts for height, but returns true when any part of the element is in the viewport:

function isVisible (ele) {
  const { top, bottom } = ele.getBoundingClientRect();
  const vHeight = (window.innerHeight || document.documentElement.clientHeight);

  return (
    (top > 0 || bottom > 0) &&
    top < vHeight
  );
}

this is the one working as of now

@stealthman22
Copy link

Great work guys @jjmu15 and Tsimons@ Your snippets are amazing. I have been looking for something like this. Didn't want to import a library to solve just one problem

@Mooh07
Copy link

Mooh07 commented Apr 26, 2022

you are probably the greatest human being in my perspective now, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment