If at first you don't succeed - make sure the element isn't set to "display:none"

by Developer @ pebbl.co.uk on Saturday, 9 July 2011

Ok, this one is going to be a slight personal moan - but I see this happening time and again with front-end web developers who haven't learned the hard way (i.e. building everything from scratch for themselves). If you are an ardent developer, and you don't find the following obvious, then maybe I should give up and go learn to make traffic cones instead.

So ... If you are having a problem with an DOM Element either not returning an expected dimension (in your own code), or seemingly having it's dimensions incorrectly set (in someone else's library code) usually to NaN or 0... Make sure you are not, or the library code is not, operating on a hidden element!

By hidden I mean having the ever-present "display" attribute 
set to "none" either on your target element, or on one of 
it's parents.

Display Nothing...

Setting display none on an element before the browser has rendered anything of that element, will mean that decent browsers will not render anything - at all - of that element..! That is the purpose of display none, it is designed to avoid the rendering of elements you want to hide. This means that accessing offsetWidth or offsetHeight (or any of the other dimension properies) will not return a correctly calculated value, becuase the rendering engine hasn't calculated one.

When is a bug not a bug?

Now the symptoms of this problem can be wide an varied, but I am still amazed at the number of people out there who seem oblivious to this restriction.. and to make matters worse, when coming across this problem either solve it entirely by accident or put it down to a bug in the browser / library they are using.

One such example of this was coming across a post on a forum where the OP was having problems working with the Google Map api. He/She was asking the forum if they had any ideas as the map just wouldn't center/position it's content correctly in IE7. The poster was describing how they were using jQuery to initially hide the map and then fade it in by way of a PopOver... and how that it worked fine when not being faded in. Now this is all well and good, the poster was clear about what they were trying to do. The thing that got me was that not one of the replies had an answer anywhere near the actual cause.

To make it almost comical, one poster actually aluded to it being a "known jquery bug" and linked off to other pages of similar discussions - where thankfully there were a few people who had described the actual cause... if not very clearly.

Examples...

So here are some examples of this confusion out in the wild, at least in each case someone does find an answer - even by way of Facebook's rather cryptic explanation in one. But the fact of the matter for me is they do not seem to fully understand that the actual cause is not a bug:

  1. http://forum.developers.facebook.net/viewtopic.php?id=95735

  2. http://forum.developers.facebook.net/viewtopic.php?id=92951
  3. http://stackoverflow.com/questions/604933/jquery-datatables-table-width-problem

Solution?

So please... If this sounds like it may be your problem, then simply change the method you are using to hide your element in the first place.


.codeSafeHide {
   position: absolute;
   left: -99999px;
   visibility: hidden;
   height: 0px;
   overflow: hidden;
}

The above will produce almost the same affect as display:none - save for the positive factor that the browser will render and calculate all widths and heights of your target element. Obviously the only value that may need changing (depending on your site) is the -99999px.. although unlikely that you will have a ridiculously wide page - it is possible - so if you are having problems getting the element to disapear off the left of the screen you can use this (although position fixed is not supported by certain older browsers):


.codeSafeHide {
   position: fixed;
   right: 100%;
   visibility: hidden;
   height: 0px;
   overflow: hidden;
}

Leave your comment