Measuring Element Dimension and Location with CSSOM in Windows Internet Explorer 9
This topic is designed to help web developers understand how to access the dimension and location of elements on the page through the CSS Object Model (CSSOM) in Windows Internet Explorer 9.
Understanding Properties That Measure Element Dimension and Location
The following diagrams represent different CSSOM properties for the same page. The sample page contains a div red element that is relatively positioned on the page. The blue element is the red element's parent. Its primary purpose is to define the different Cascading Style Sheets (CSS) boxes that compose an element's layout, as well as to show how the offsetTop property is calculated. The viewport is the black outline, and is represented by the html element. In the diagrams, the html element is not shown with any margin or border. Adding a margin or border would not change any of the measurements, however.
Because the overflow attribute of the div has been set to "scroll" and it contains more content than can be displayed within its limited client area, scroll bars are displayed. Be aware that the values illustrated are all the vertical-oriented properties. The horizontal-oriented properties are similar; simply substitute "left" for "top", "width" for "height", and so on.
For more information about any of these properties, see Reference.
The following diagram illustrates vertical sizing and positioning values for the red element.
Note When elements are scrolled such that they are partly visible at the top of the viewport, the getBoundingClientRect().top property returns negative values.
The following diagram illustrates vertical sizing and mouse coordinate positions that are affected by CSS transforms. Be aware that the offsetY coordinates are reported in the red element's original coordinate space (that is, as if the element were not transformed). This is in contrast to layerY, which is reported in the transformed coordinate space (that is, according to the dimensions of the bounding box).
The following diagram illustrates all vertical mouse coordinates and viewport offsets on an untransformed element. Be aware that, in Internet Explorer 9, when the page has been scrolled, the layerY value includes the window.pageYOffset amount in the value. This is incorrect behavior, and will be fixed in a future release.
Also, in this diagram, the viewport has been scrolled down such that there is additional content available "above" the viewport. This is designed to show that each property—pageY, clientY, layerY, and offsetY—corresponds to a different relative coordinate point when the document has been scrolled.
Finding an Element's Location Relative to the Page Origin
An element has convenient CSSOM properties to find its location relative to the element's offsetParent or the viewport. There is currently no CSSOM property to directly locate an element based on the page (document) origin (for instance, similar to the pageX/pageY properties for mouse events).
A common solution to find the element's location relative to the page involves summing the value of offsetTop with the element's offsetParent.offsetTop and so on until offsetParent returns null. (Naturally, offsetLeft is used for horizontal positioning.) Avoid this practice for the following reasons:
- The offsetTop value does not include the width of the offsetParent's border. This can lead to slight misalignments when any element in the offsetParent chain has a border style applied.
- These repeated summations can contribute to slow performance when offsetParent chains are long.
With Internet Explorer 9, it is better to use the newly added window.pageYOffset property (window.pageXOffset for horizontal scenarios). The recommended practice to find an element's vertical location from the page's origin is to add the element's getBoundingClientRect().top property to the window.pageYOffset value. (getBoundingClientRect().left + window.pageXOffset for the horizontal location.) This yields the correct result avoiding both pitfalls previously shown.
Coordinates relative to the page origin (document origin, regardless of viewport scrolling):
- pageX, pageY (location of the mouse)
- pageXOffset, pageYOffset (location of the viewport)
Coordinates relative to the viewport origin (visible area of the page):
- getBoundingClientRect().top, bottom, left, right (location of the element's border box/bounding box when CSS transforms are applied)
- getClientRects().top, bottom, left, right (same as above)
- clientX, clientY (location of the mouse)
Coordinates relative to an element's margin box origin (unaffected by CSS transforms):
- getComputedStyle().marginTop, marginLeft (location of the element's border box)
Coordinates relative to an element's border box origin (unaffected by CSS transforms):
- clientTop, clientLeft (location of the element's padding box)
- getComputedStyle().borderTopWidth, borderLeftWidth (same as above)
- offsetHeight, offsetWidth (dimension of element's border box)
Coordinates relative to an element's border box/bounding box (when CSS transforms are applied):
- getBoundingClientRect().height, width (dimension of element's border box/bounding box)
- layerX, layerY (location of the mouse)
Coordinates relative to an element's padding box (unaffected by CSS transforms):
- clientHeight, clientWidth (dimension of the element's padding box, less scrollbar track when visible)
- getComputedStyle().paddingTop, paddingLeft (location of the element's content box)
- offsetX, offsetY (location of the mouse)
Coordinates relative to an element's content origin (when content overflows producing scrollbars):
- scrollTop, scrollLeft (location of the padding box)
- scrollHeight, scrollWidth (dimension of the overflow content)
Coordinates relative to an element's content box (unaffected by CSS transforms):
- getComputedStyle().height, width (dimension of the content box)
Coordinates relative to an element's offsetParent (padding box of the offsetParent):
- offsetTop, offsetLeft (location of the border box)