13

This seems like it should be fairly easy - but I can't find the right selector for it

According to the docs (http://api.jquery.com/hidden-selector/ and http://api.jquery.com/visible-selector/)...

Elements can be considered hidden for several reasons:

An ancestor element is hidden, so the element is not shown on the page.

What I want to detect is "this element is visible, but is contained in a hidden parent". Ie, if I made the parent visible, this element would also be visible.

Paul
  • 9,409
  • 13
  • 64
  • 113

3 Answers3

27

If this is something you'll commonly use, make your own selector :) Here's an example:

jQuery.expr[':'].hiddenByParent = function(a) { 
   return jQuery(a).is(':hidden') && jQuery(a).css('display') != 'none'; 
};

You can use it like this, test markup:

<div style="display: none" id="parent">
  <div>
      <div id="child">Test</div>
  </div>
</div>
​

Examples of use:

$("div:hiddenByParent").length;​​​​​​​​​​​​​​​​​​ // "2" (plain div + child match)
$("#child").is(":hiddenByParent"); // true

Alternatively, you can use the .filter() function like this:

$('selector').filter(function() {
  return $(this).is(':hidden') && $(this).css('display') != 'none';
}
Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • 1
    Great answer as always Nick! But if an element has the visibility set to hidden, then you will need to use this as the selector `return $(a).is(':hidden') && $(a).css('display') != 'none' && $(a).css('visibility') == 'visible';` – Mottie Mar 31 '10 at 16:45
  • 1
    @fudgey - Good point, `visible` stuff isn't "hidden" though, it does still occupy the space on the page. I guess it depends if you're looking for totally hidden things or things that take up no room on the page at all. Whatever definition you're after, use that approach for sure. – Nick Craver Mar 31 '10 at 17:05
  • Brilliant! Just the answer I wanted, and first Google result too. I'd only add to say I think a nicer selector name would be ":invisible". It's "visible" ... but *in*visible. – Dave Stewart Oct 18 '12 at 18:28
5

jQuery has this all built-in nowdays

$("#child").closest(':hidden').length == 0
root
  • 2,327
  • 1
  • 22
  • 18
1

If it is a specific element that you are looking for then you could check it's display property

$('#element').css('display') != 'none';

If it wasn't a specific element then you could find the parent nodes that are hidden using :hidden then use a custom function to look for nodes of the type you want. E.g.

$('parent-selector:hidden').find('node-selector').each(function(){
  if($(this).css('display') != 'none') {
    // do what you wanted
  }
});

If you want a clean selector then i think that you're going to be out of luck as i don't think what you want is part of the CSS spec, so won't be there as a selector in jQuery.