#172 new
Benjamin St

Offsets and non-scrollable Areas (IE)

Reported by Benjamin St | February 19th, 2009 @ 12:10 AM

The coordinates returned by cumulativeOffset() do not include the remaining offsets when the page contains a non-scrollable area (fixed header) on top or left of the page.

Example layout:


| | CONTENT (X) | | | | | | (Droppable) | | LEFT MENU | | | | (Draggable1) (Draggable2) |

| | |


The example above shows a Drag and Drop szenario from our portal page. The draggable will be recognized at the wrong position in IE (marked with (X)).

The offset difference is exactly the bogus offsetHeight/Top and offsetLeft returned by IE: Assume the top header is 100px, the left header is 200px, and the Droppable is at (x=600, y=300) --> IE will return offsetHeight=200 (less 100), the left offset will however get additional offset of exactly the difference between the content page and the left viewport border. Firefox reports the correct 300px offset.

For obvious reasons the fixed header is not a parent of the content area, and cumulativeOffset() has to rely on the offset of the last element. I think this is clearly an IE misbehavious, since there is no feasible way to compute the offset when there is no parent to the content area.

I tested this with a bunch of YAML based layout on our portal site which shows all the same behaviour. Pages styles without fixed areas work fine.

My current workaround is this:

On my page script I calculate the offsets for the left menu ("col1" for my site) and the header menu:

// Put someplace in your script

    var nonScrollOffsetTop = 0;
    var nonScrollOffsetLeft = 0;
    if (document.getElementById('fixed_header') && document.getElementById('col1')) {
        var header = document.getElementById('fixed_header');
        // Höhe des Portal Headers + Abstand zum oberen Rand
        nonScrollOffsetTop = getElementHeight(header) + header.offsetTop;
        var leftMenu = document.getElementById('col1');
        // Breite des linken Portalmenüs + Abstand zum linken Rand
        nonScrollOffsetLeft = getElementWidth(leftMenu) + leftMenu.offsetLeft;
        newImg = $(newImg);
        if ( navigator.appName == "Microsoft Internet Explorer") {
            Position.nsrOffsetX = nonScrollOffsetLeft;
            Position.nsrOffsetY = nonScrollOffsetTop;

function getElementWidth(el)
    return el.offsetWidth ? el.offsetWidth : el.innerWidth;

function getElementHeight(el)
    return el.innerHeight ? el.innerHeight : el.offsetHeight;

The changes for prototype.js are the additional offsets nsrOffsetX and nsrOffsetY (for time constraints I just attached my prototype.js, latest git, aned marked all changed lines with "B.S." for lookup).


Comments and changes to this ticket

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป

script.aculo.us is an open-source JavaScript framework for visual effects and interface behaviours.
<br/><b>Source available from github</b>
The Git repository resides at:
<a href="http://github.com/madrobby/scriptaculous">http://github.com/madrobby/scriptaculous</a>
<br/>Check out the current development trunk with:
<code>git clone git://github.com/madrobby/scriptaculous.git</code>
<br/>As <b>script.aculo.us 1.xx is feature-frozen</b>, this development trunk is for <b>bugfixes only</b>.
<br/>New development should happen only for
<b>script.aculo.us 2</b>.
<br/><b>Creating a bug report</b>
When creating a bug report, be sure to include as much relevant information as possible. Post a an example that shows off the problem. Preferably, <b>alter the unit tests</b> and show through either changed or added tests how the expected behavior is not occuring.

People watching this ticket