Robust Get Element Dimension Function

As mentioned earlier this week, today we will be discussing a getDimension function that corrects for certain styles ("display:none" and "overflow:hidden") that cause an element to not have the proper height/width. This method contains generic logic that will determine if the element is "display:none" or "overflow:hidden", whether styled inline or via CSS (thanks to YUI), and temporarily correct those styles to determine the actual height/width of the element. It works with any element (not just block level), will restore any styles that it changes, and allows you to override the default correction behavior.

Example 1: getDimension

Dom.getDimension = function(elem, ignoreDisplay, ignoreOverflow) {
    var node = Dom.get(elem),
        x = 0,
        y = 0,
        width = 0,
        height = 0;

    // node exists
    if (node) {
        var stl = node.style,
            originalDisplay = Dom.getStyle(node, display),
            originalOverflow = Dom.getStyle(node, overflow),
            originalPosition = Dom.getStyle(node, position),
            originalVisibility = Dom.getStyle(node, visibility),
            originalHeight = node.offsetHeight,
            correctDisplay = none === originalDisplay && ! ignoreDisplay,
            correctOverflow = hidden === originalOverflow && ! ignoreOverflow;

        // not displayed; temporarily display
        if (correctDisplay) {
            stl.visibility = hidden;
            stl.position = absolute;
            stl.display = block;
        }

        // overflow hidden; attempt to correct
        if (correctOverflow) {
            stl.visibility = hidden;
            stl.position = absolute;
            stl.height = auto;
        }

        // determine dimensions
        var region = Dom.getRegion(node);
        x = region.left;
        y = region.top;
        width = region.right - x;
        height = region.bottom - y;

        // restore overflow
        if (correctOverflow) {
            stl.height = originalHeight + px;
            stl.visibility = originalVisibility;
            stl.position = originalPosition;
        }

        // restore corrected display
        if (correctDisplay) {
            stl.visibility = originalVisibility;
            stl.position = originalPosition;
            stl.display = originalDisplay;
        }
    }

    return {x: x, y: y, height: height, width: width};
};

*Note: I assume that you are using YUIs "yahoo-dom-event.js" and that you have a shortcut "Dom" that points to YAHOO.util.Dom".

First we ensure that the element is an Element object, not an ID string, and initialize default value of ZERO for each dimension. When the node exists in the DOM we fetch the required styles using the YUI "Dom.getStyle" method, which corrects for styles applied via CSS, and determine if we need to correct for "display:none" or "overflow:hidden". You can prevent these corrections if you set either ignoreDisplay or ignoreOverflow to true. If we need to correct the display, we style the visibility to hidden, so it wont appear when we style the element "display:block", and position it absolute so that it wont move other elements around in the DOM. If we need to correct for the overflow, we do the same, but instead of applying "display:block", we set the height to auto, which will cause the element height to reflect its contents. Then we determine the dimensions using the YUI "Dom.getRegion" method, which returns the top, right, bottom, and left values of the element. Lastly, before returning the dimensions, we restore any height, visibility, position, and/or display styles to their original values.

This method has fairly simple logic, but is immensely helpful if you need the full dimension of elements that are not or might not be displayed. I put together a test page, so that you can see getDimension in action.