Width and height of element inside invisible ancestor
Prototype.js provides a nice getDimensions() method to determine dimensions of an element with display:none style set. This method works fine on such elements, but when you need to fetch dimensions of an element which is a descendant of other hidden element it just returns {height: 0, width: 0}.
Although this was reported issue it is still not fixed (as of prototype-1.6.0.3). You could find the ticket #11142 on old Trac system and the discussion on old prototype's group Ruby on Rails: Spinoffs.
Until the fix is released, you can replace original prototype's getDimensions() function with the one from patch:
Element.addMethods({ /* * You can use getDimensions function name to replace original function * or choose some other name to distinguish between this version and * prototype's one, to not break backward compatibility with your existing code and workarounds. */ getDimensions: function (element) { element = $(element); var dimensions = {width: element.clientWidth, height: element.clientHeight}; if ((dimensions.width || dimensions.height) == 0) { // All *Width and *Height properties give 0 on elements with display none, // or when ancestors have display none, so enable those temporarily var restore = element.ancestors(function(element) { return !element.visible() }), styles = []; restore.push(element); restore.each(function(r) { styles.push({ display: r.getStyle('display'), position: r.getStyle('position'), visibility: r.getStyle('visibility') }); r.setStyle({display: 'block', position: 'absolute', visibility: 'visible'}); }); dimensions = {width: element.clientWidth, height: element.clientHeight}; restore.each(function(r, index) { r.setStyle(styles[index]); }); } return dimensions; }//getDimensions });
If the element is visible the function returns its dimensions immediately, otherwise it iterates over ancestors of the element, makes them temporarily visible, determines dimensions, and restores original visibility state. This method is internally used by getWidth() and getHeight() so those methods should also return correct values, when getDimensions() is repalced.
Note: This is usually fast enough so the user do not notice any change, but it might happen, on heavy system load, that the invisible elements appear for a second on screen.
You can try a very basic live demo.