19

I'm interested in a way to check whether an element has display:none style explicility (ie style="display:none"), has a class that has (or inherits) this style, or one of its parents is hidden (and my element inherits this)

Case1:

<body><div><span style="display:none;">Some hidden text</span></div>

or

<body><div style="display:none;"><span>Some hidden text</span></div>

Case2:

SomeClass {   display:none;   }
<body><div class="SomeClass"><span>Some hidden text</span></div>

Thanks,

Haytham
  • 225
  • 1
  • 2
  • 7

5 Answers5

32

You are looking for one solution to two different scenarios.

The first scenario is getting the cascaded/computed style for a css property. See this answer for how to do that.

The second scenario is detecting if any of an element's parents are hidden. This requires traversing and is cumbersome and slow.

You can take the solution outlined here (and employed by jQuery/Sizzle since 1.3.2), and just read the dimensions of the element:

var isVisible = element.offsetWidth > 0 || element.offsetHeight > 0;

If it has dimensions then it is visible in the sense that it takes up some rectangular space (however small) in the document. Note that this technique still has some downsides for certain elements in certain browsers, but should work in most cases.

Community
  • 1
  • 1
Crescent Fresh
  • 115,249
  • 25
  • 154
  • 140
  • no need to traverse, I only need to check the parent if this will affect the computed style, hence the computer style is enough for me... thanks for your answer, it helped a lot, here is the code I finally used: function IsVisible(elem) { if (elem.currentStyle) // ie only { return elem.currentStyle["display"] != 'none'; } else { // jquery way for computing isvisible. return (elem.offsetWidth > 0 || elem.offsetHeight > 0); } } however, I need to do more testing to see whether "||" is enough or do I need to have "&&" instead.. – Haytham Aug 27 '09 at 23:50
  • 3
    The jQuery/Sizzle 1.3.2 link is broken, you can now [find it here](https://github.com/jquery/jquery/blob/1.3.2/src/selector.js#L961). – Simon Lieschke Nov 23 '10 at 01:13
  • As of writing the current solution used in jQuery with downsides fixed can be found [here](https://github.com/csnover/jquery/commit/0229b83f7e5bf64edb2888ab349bedcd1a45e7c1#L0L281). Further discussion [here](http://bugs.jquery.com/ticket/4512). – Simon Lieschke Nov 23 '10 at 02:12
  • This is just a note to say that I've just tested the above solution with IE8 and it seems to be working as expected so the [downsides](http://groups.google.com/group/jquery-dev/browse_thread/thread/0334b35ecd875253) mentioned by @Crescent Fresh may no longer apply. I tested IE8 version 8.0.7601.17514. – Malice Apr 06 '11 at 14:03
  • "var isVisible" is misleading and should really be "var isDisplayed" in this context, particularly as this answer does not work for "visibility: hidden" where the element still has offset even though it cannot be seen – Pancho Sep 06 '15 at 21:26
  • @SimonLiescke's link is broken. Folks, this is why you give information, not provide links to information. – John Smith Nov 15 '18 at 17:01
6

This is the quickest and easiest way to determine if an element is visible.

function is_visible(e) {return e.offsetWidth > 0 || e.offsetHeight > 0;}
John
  • 1
  • 13
  • 98
  • 177
Josh Stodola
  • 81,538
  • 47
  • 180
  • 227
3

Each case will need its own check and you need to know the ID of that element. First, grab the element (just doing this to make the code readable):

var MyElementName = document.getElementById("MyElementName");

Then do your checks:

Case 1:

 if (MyElementName.style.display == "none")

Case 2, looking at the parent, checking FF first:

if ((MyElementName.previousSibling.nodeType == 3 )
    && (MyElementName.parentNode.nextSibling.style.display == "none"))

then for other browsers:

else (MyElementName.parentNode.style.display == "none")

Case 3, look for an applied css class:

if (MyElementName.className = "SomeClass")
Andrew Magill
  • 2,254
  • 4
  • 21
  • 28
1

The above solution caters for this "invisibility" scenario:

display:none;

but it does not cater for this one:

visibility: hidden;

In order to include the test for visibility: hidden; the script can be modified as follows...

First, create a cross browser compliant function to get the desired element's computed style:

computedStyle = function(vElement) {
  return window.getComputedStyle?
         ?window.getComputedStyle(vElement,null)
         :vElement.currentStyle;                    //IE 8 and less
}

Second, create the function to test for visibility

isVisible = function(vElement) {
  return !(vElement.offsetWidth == 0 && vElement.offsetHeight == 0)
         && computedStyle(vElement).visibility != "hidden";  
}

Finally, simply reference the isVisible function wherever needed as follows:

if (isVisible(myElement)) {
  alert('You can see me!');
} else {
  alert('I am invisible ha ha!');
}

Just a note that the current isVisible() tests do not cater for a number of "invisibility" scenarios (however the tests could I suppose be enhanced to include these). Here are a few examples:

  1. where an element is the same colour as the surrounding colour
  2. where an element is visible but physically behind another element eg. different z-index values

It is also probably worth noting the following regarding the above computedStyle() function:

  1. It can of course be used for many other style related purposes besides testing visibility
  2. I have opted to ignore :pseudo style testing due to patchy browser support, however with a minor modification to the function this could be included if desired.
Pancho
  • 2,043
  • 24
  • 39
-1

Is this what you are trying to do?

function SomeClass()
{
  if (document.getElementById("MY_DIV_ID").style.display == "none")
  {

  }
}
Mark
  • 261
  • 1
  • 4
  • 9
  • I don't think this is what he wants... i think he wants a way to check it if its set by a class or if its done inline, this way will only work if it is done inline – Zoidberg Aug 27 '09 at 19:25