Manso jQuery Trick: is the element really visible

Sometimes is essential to know if an element is visible or hidden. Doing this with jQuery is quite easy, you have to ask if the filter “visible” is present or not (you can also use ‘hidden‘). However you should take care and notice a couple of things, because maybe jQuery is not telling us the truth about the visibility of the object being queried.

The problem appears when we are asking about the div X and the parent is hidden. It is a problem because when a div is hidden, all its childs are also hidden, but when we ask jQuery about the div X it doesn’t matter if any of its parents is hidden or not, it will only check the visibility of the div X by itself, which sometimes is fine, but some others is not.

Like I always do, let’s see a couple of examples.

Ejemplo 1:

Let’s start from the beginning. If I’m using the following HTML code:

<div id="DivBlock">Element</div>

Then after executing the following javascript code we will see two alerts, the first one saying “Visible!”, and the second one saying “Not Hidden”.

if ($('#DivBlock').is (':visible')) alert ("Visible!");
if (!$('#DivBlock').is (':hidden')) alert ("Not Hidden");

Up to this point everything work just fine. As you can see, asking if a layer is visible or not in jQuery is quite easy.

Ejemplo 2:

Let’s try something harder.Let’s see what happens if the parent div is hidden:

  <div style="display: none;">
   <div id="DivBlock">Element</div>
  </div>

Again, if we run the same javascript code (that I copied again), you will see that every single browser but Safari will show the alerts, saying that the div is visible, but wait, the element is, in fact, hidden!!.

if ($('#DivBlock').is (':visible')) alert ("Visible!");
if (!$('#DivBlock').is (':hidden')) alert ("Not Hidden");

Oh my god! ¡¡jQuery is doing it wrong!! (forget the dramatism here ;) in fact it seems more a browser implementation issue.

Anyway, fortunately we have a solution for this, and it’s quite easy. If you want to ask if the div X is really visible, you sould ask are X and all its parents visible?, or in other words is it X visible and are all their parents not hidden? which in jQuery translates to:

if ($('#DivBlock').is (':visible') && $('#DivBlock').parents (':hidden').length == 0)
  alert ("Visible!");

The code above should work perfectly in all browsers.

Finally, as an alternative solution, a selector could be created to make it easier to ask from jQuery:

jQuery.extend(
  jQuery.expr[ ":" ], 
  { reallyvisible : "(jQuery(a).is(':visible') && jQuery(a).parents(':hidden').length == 0)" }
);

Using the new selector, asking if DivBlock is really visible will be coded as following:

if ($('#DivBlock').is (':reallyvisible'))  alert ("Visible!");

For more information:

Trackback URL

312 Comments on "Manso jQuery Trick: is the element really visible"

  1. adrive
    03/06/2009 at 1:02 pm Permalink

    Great job! Your :reallyvisible selector should definitely be in the core!

  2. Jiri Melcak
    05/08/2009 at 12:16 pm Permalink

    Thanks very much. Help me a lot this evening.

  3. Aamir Afridi
    21/08/2009 at 7:27 am Permalink

    Awesome man… Very very helpful…

  4. Ian Holmes
    09/09/2009 at 1:01 am Permalink

    Thanks for the article – well explained and eay to follow. However, the syntax for your extension to the jQuery selector engine does not work – try this instead:

    jQuery.extend(jQuery.expr[":"],{reallyvisible: function(a) { return (jQuery(a).is(‘:visible’) && jQuery(a).parents(‘:hidden’).length == 0) }});

  5. Revenue Robot
    11/12/2009 at 1:37 pm Permalink

    awesome thanks for posting this it was what i’ve been looking for…

  6. Drew
    17/07/2011 at 11:34 am Permalink

    @ Ian Holmes,

    Thanks for reposting the extension, I couldn’t get the original one to work either.
    I had to change the backticks to quotes around the :visible & the :hidden text…

    jQuery.extend(jQuery.expr[":"],{reallyvisible: function(a) { return (jQuery(a).is(‘:visible’) && jQuery(a).parents(‘:hidden’).length == 0) }});

    Hopefully it isn’t the filters on the site causing the backticks.

  7. Virendra
    10/02/2012 at 3:28 am Permalink

    Your post is good but these attribute doesn’t work when visibility=hidden is used to hide the element. I faced this situation and after sometime got the solution as well. So thought of sharing with you.

    http://jquerybyexample.blogspot.in/2012/02/how-to-check-element-visible-or-hidden.html

Hi Stranger, leave a comment:

ALLOWED XHTML TAGS:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">

Subscribe to Comments