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, 2014

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, 2014

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, 2014

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, 2014

@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, 2014

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, 2014

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, 2014

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, 2014

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, 2014

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, 2014

@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, 2014

@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, 2014

@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, 2014

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

Scott Mitting on 17 October, 2014

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, 2014

Thank you for a great tool I was looking for!

Something to say?

The is a flightless bird and a symbol of NZ

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