getBoundingClientRect is a method, first introduced by Internet Explorer 5 (and now included in Firefox 3), which provides the top, right, bottom, and left offset coordinates of an element. After PPK mentioned this method in a recent post of his, poo-poo-ing its applicability, I thought I’d take some time to show how useful it can be. What makes this method so especially handy is that the alternative means of computing an element’s offset position is so horribly slow and buggy that it borders on the comical.
The general purpose of this method, or of similar implementations, is to allow the user to get the visual top/left position of an element (such that if they absolutely position an element from the document it would be on top of the desired element – making things like tooltips possible, to name a single application). This means that you have to take into account a huge number of quirks. In no particular order here are some choice bugs which make this very difficult:
- Handling table border offsets.
- Fixed positioned elements.
- Scroll offsets within another element.
- Borders of overflowed parent elements.
- Miscalculation of absolutely positioned elements.
For example, looking at jQuery’s implementation of .offset() (which provides the top/left offset of an element) we can see a number of these quirks worked around. A phenomenal amount of work has gone into the method, by the excellent Brandon Aaron, in order to “get it right” in a cross-browser manner. Check out the extensive suite of tests that are backing it up, as well.
This is where getBoundingClientRect comes into play. For a visual comparison look at the green boxes (representing the getBoundClientRect-based implementation) versus the red boxes (representing the normal cross-browser implementation).
The reason why the getBoundingClientRect implementation is more than 1 line is due to two facts:
- It doesn’t include the document scroll offset (which is a simple addition).
- Internet Explorer’s handling of <html/> element border widths is completely whack.
In comparison to the default technique, however, this is a veritable walk-in-the-park.
Now, not only, is this method simpler to use it’s also insanely faster. Stupifyingly so. Considering that you no longer have to perform all sorts of hacks, or walk the tree to rectify miscalculations, the result is quite impressive.
View the following jQuery UI drag-and-drop sorting demo page in Firefox 2 (drag the items in the grid, at the bottom) and then view it in Firefox 3, doing this same:
Night and day. I’ve also uploaded a simple movie demonstrating the difference.
I absolutely encourage everyone to check this method out. It can serve as a near-drop-in replacement for your offset needs – and will gracefully work in new browsers that support the method.