Follow us on Twitter

Web

Checking if an element is visible on-screen using jQuery

by Sam Sehnert

Download jQuery VisibleView Demo

We recently built a little jQuery plugin which allows us to quickly check if an element is within the browsers visual viewport, regardless of the scroll position. If a user can see this element, the function will return true.

?The visual viewport is the part of the page that?s currently shown on-screen. The user may scroll to change the part of the page he sees, or zoom to change the size of the visual viewport.? PPK

This method differs from the jQuery :visible selector in that visible checks to see whether the element is hidden using css (basically if offsetWidth or offsetHeight is 0). Our method checks if an element can be seen based on its position relative to the viewport.

Usage


In its simplest form, the element can be used as follows:

$('#element').visible()

This method will return true if the entire element is visible (I.e., it will return false if any part of that element is outside the viewport.
Passing true to the ‘visible’ method, will tell the plugin to return true if ANY part of the element is visible on the users screen.

$('#element').visible( true )

Limitations

The plugin ignores the elements visibility (E.g., display:none; visibility: hidden; offsetWidth or offsetHeight is 0). To filter on css visibility, you can use the jQuery :visible selector:

$('#element:visible').visible()

Currently the plugin only checks for vertical positioning and scroll. We’re planning on adding horizontal support soon, with the ability to optionally run the check on horizontal, vertical or both planes.

Download jQuery VisibleView Demo

Comments

Daniel on 13 February, 2015

Looks great! I need something like that, to allow a kind of lazy-load of many images inside a scrollable container. Lets say something about:


    Div 1
    Div 2
    Div 3

The function should return div 1 and 2. I'll take a look at the source of your plugin to see if fit my need! Thanks for sharing!

Shawn on 23 April, 2015

I'm having an issue with this and other methods that try the same thing. Essentially onscroll event I call a function that has this code to see if a div is visible. If it is I then load more results (think facebook news feed) which will then move the div further down the screen. Everything works as expected but for some reason when there are no more results to load and the scrollbar is all the way to the bottom you can not click and drag the scrollbar back up.

Lionel Agonero on 27 April, 2015

Great work! I have no idea how to use your method for images for example in the gallery, because there are more that one elements may be with the same selector. Is it possible to use your function with .each?

Sam Sehnert on 14 May, 2015

@lionel, Check out this article on css-tricks.org: http://css-tricks.com/slide-in-as-you-scroll-down-boxes/ It demonstrates quite nicely how this plugin can be used with .each.

jess jakka on 20 July, 2015

Really nice and simple plugin! It would be nice if instead of passing "true" to .visible(), you could instead pass a number like ".75" which represents the % of the item that is atleast visible.

jess jakka on 20 July, 2015

something like this: $.fn.visible = function(partial) { var $t = $(this), $w = $(window), viewTop = $w.scrollTop(), viewBottom = viewTop + $w.height(), elTop = $t.offset().top, elVisibility = (viewBottom - elTop) / $t.height(), return ( elVisibility >= partial);

Michael Barker on 26 September, 2015

Hey guys, this is brilliant! I'm getting an error when the items that I'm checking for aren't on the page (this plugin is on every page with the rest of my scripts) Uncaught TypeError: Cannot read property 'top' of undefined Is there a fix for this? Thanks!

Bernard on 01 December, 2015

This does not seem to work when the element in question is scrolled out of visibility, but still within the screen. I cannot see it, but still the plugin tells me its visible. Please advise.

Sam Sehnert on 18 February, 2015

Hey, nice suggestion, @jess ? I'll be sure to add that into the next version. @michael, Thanks for the report, I'll address this in the next release. @bernard, are you talking about partial visibility vs full visibility on the window? Or are you referring to a parent element with overflow: scroll; set?

Bernard on 19 February, 2015

@Sam Sehnert Thanks for the reply. The parent element has overflow:auto. So the child element in question can be scrolled out of view, 'behind', so to say, another element, but still within the window or viewport, whatever you call it. Cheers!

Sam Sehnert on 19 February, 2015

@bernard, Ok thanks. We've got an issue logged for this on GitHub. I do like the idea of supporting this, but I can't make any promises about when I'll be able to implement this. https://github.com/teamdf/jquery-visible/issues/11 As always, you're more than welcome to have a go at making the change yourself and submitting a pull request.

jason on 21 May, 2015

@michael_barker maybe your version of jquery isn't compatible with this plugin? @sam What's the minimum jq version number this plugin should be working with?

J.Ko on 31 August, 2015

This works great~ thanks for all your work so i don't have to put in mine.

Scott Mitting on 17 October, 2015

Just noticed that this doesn't work for my current situation, although it may be rare. I have an iframe expanded so that the parent page scrolls instead of the iframe, and .visible() isn't working correctly in this situation. We are doing this because we are upgrading an old existing ASP.Net forms application to behave like modern single-page web apps (and this works surprisingly well) so this might not be something anyone else will ever run across. However, your source is still super useful for me to create my own solution for this, so thanks a million!

Veaceslav Cartera on 10 November, 2015

Thank you for a great tool I was looking for!

Sukhwant Atwal on 16 January, 2015

Is there any way to offset when an element becomes 'visible'? I'm using this plugin as part of a solution to get around the perennial problem of starting animation GIFs when you scroll down to them (instead of whenever the image finishes loading..so you dont have the situation where the animation is already played before you scroll down to it!) My solution kinda works but as the plugin fires immediately an animating GIF is visible in the viewport (ie the very top)...you've got to scroll quick to view the animation! Is there any way to offset when the element in question becomes 'visible'... i.e wait until the element is completely within the viewport before returning visible:true? I'm probably doing it wrong 8-)

Sam Sehnert on 16 January, 2015

@sukhwant, Do you have an example of what you've tried? There are two options described in the article — one will return TRUE when the element is PARTIALLY visible (i.e., a single pixel in the viewport), and the other will return TRUE when the element is COMPLETELY visible. $('#element').visible( false ); // Pass FALSE or no parameter to get the plugin to return TRUE when the element is COMPLETELY visible.

Something to say?

Our company is named Digital

Some HTML is OK
  • <b>bold</b>
  • <i>italic</i>
  • <blockquote>
    blockquote
    </blockquote>
  • <pre>
    preformatted code
    </pre>