18

I am trying to do positioning in JavaScript. I am using a cumulative position function based on the classic quirksmode function that sums offsetTop and offsetLeft for each offsetParent until the top node.

However, I am running into an issue where the element I'm interested in has no offsetParent in Firefox. In IE offsetParent exists, but offsetTop and offsetLeft all sum up to 0, so it has the same problem in effect as in Firefox.

What would cause an element that is clearly visible and usable on the screen to not have an offsetParent? Or, more practically, how can I find the position of this element in order to place a drop-down beneath it?

Edit: Here's how to reproduce one particular instance of this (not solved by the currently-accepted answer):

  1. Open the home page of Stack Overflow.
  2. Run the following code in the Console of the web browser (e.g. Chromev21):

    var e = document.querySelector('div');
    console.log(e);
    // <div id="notify-container"></div>
    do{
      var s = getComputedStyle(e);
      console.log(e.tagName,s.display,s.visibility,s.position,e.offsetParent);
    } while(e=e.parentElement)
    // DIV block visible fixed null
    // BODY block visible static null
    // HTML block visible static null
    

Why is the offsetParent of that element null?

Phrogz
  • 296,393
  • 112
  • 651
  • 745
Brian Ramsay
  • 7,536
  • 8
  • 41
  • 52

7 Answers7

51

I have made a test of 2,304 divs with unique combinations of values for position, display, and visibility, nested inside unique combinations of each of those values, and determined that:

an otherwise-valid element
that is a descendant of <body>
will not have an offsetParent value if:

  • The element has position:fixed (Webkit and IE9)
  • The element has display:none (Webkit and FF)
  • Any ancestor has display:none (Webkit and FF)

It is also reasonable to expect that an element that has no parent, or that is not added to the page itself (is not a descendant of the <body> of the page), will also have offsetParent==null.

Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • Thank you very much, you answer made me understand why this code https://stackoverflow.com/a/21696585/4481831 worked in FF but not in Chrome. – crisc2000 Nov 28 '19 at 22:52
17

If the document hasn't finished loading then offsetParent can be null

Greg
  • 316,276
  • 54
  • 369
  • 333
13

https://developer.mozilla.org/en/DOM/element.offsetParent

offsetParent returns null when the element has style.display set to "none".

Ivan
  • 1,511
  • 16
  • 22
  • 4
    Per my answer below, I've now edited the MDN page to note that there are other situations for non-FF browsers that also cause the situation. – Phrogz Jul 24 '12 at 22:00
  • is not as simple as you say it. offsetParent will also return null if style.display is for example "block" but one of the element parents style.display is "none". that why this method is used for checking the visibility of an element better then "getComputedStyle" method that do not check for parents. – crisc2000 Nov 28 '19 at 22:55
4

This is an old question, but I have another case. If you manipulate the DOM, you may end up with a null offsetParent - in IE6 and IE7.

See: IE 6/7 - "Unspecified Error" when accessing offsetParent (Javascript)

kapa
  • 77,694
  • 21
  • 158
  • 175
Mark
  • 999
  • 9
  • 19
4

offsetParent will return null if your element object hasn't been appended to the DOM yet.

David Rivers
  • 2,896
  • 1
  • 31
  • 39
0

I have run into this problem when the sibling just to the left of the element is hidden:

<div id="parent">
  <div id="element1">some stuff</div>
  <div id="element2" style="display: none">some hidden stuff</div>
  <div id="element3">child whose offset we want</div>
</div>

I've run into the case where the offsetParent of element3 is null even though element3 itself is visible, and parent is visible.

I've seen thin is Firefox 3.6 and Chrome 5. It seems to also affect the getBoundingClientRect() function on the element3, which is really annoying since that works in so many other cases!

Norman
  • 21
  • 3
0

I also experienced an offsetParent of null when the parent was inside a web component (i.e. the element I tried getting the offsetParent of was projected into the web component).

t.animal
  • 3,012
  • 1
  • 24
  • 25