Getting absolute width of margins (issue with margin: auto;)

I'm trying to determine the used value of the margins of an element. My understanding is that this should be returned via .getComputedStyle(). However, it seems that FireFox and Opera don't return the correct values when margin: auto; is used. Firefox returns '0px', and Opera returns '0px' or, occasionally, 'auto':

http://jsfiddle.net/8FXbZ/

I know I could calculate the content width of the parent, and the total width of the child, and use those to calculate the margins, BUT I'm primarily looking at the case when the parent is a flexbox:

http://jsfiddle.net/8FXbZ/1/

Again, the values could possibly be 'reverse-engineered' but that would get relatively complicated (especially if the flexbox has wrapping allowed), so I was wondering if anyone had any other thoughts?

Answers:

Answer

There is a bug in Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=381328 that returns the wrong value.

Answer

I know this isn't the answer you are looking for. Given the bug, here's a poly-fill I started to calculate the left and right margins. FIDDLE

function getMargin(elem) {
  var parent = elem.parentNode,
    prev = elem, 
    next = elem, 
    leftEdge, 
    rightEdge;

  var pos = elem.getBoundingClientRect();
  var parentPos = parent.getBoundingClientRect();
  var parentComputed = window.getComputedStyle(parent);
  while((prev = prev.previousSibling) && !prev.getBoundingClientRect){}
  while((next = next.nextSibling) && !next.getBoundingClientRect){}
  if(prev)
    leftEdge = prev.getBoundingClientRect().right; //+ getMargin(prev).right
  else {
    leftEdge = parentPos.left + parseInt(parentComputed.getPropertyValue("padding-left")) + parseInt(parentComputed.getPropertyValue("border-left-width"))
  }
  if(next)
    rightEdge = next.getBoundingClientRect().left; //- getMargin(next).left;
  else {
    rightEdge = parentPos.right - parseInt(parentComputed.getPropertyValue("padding-right")) - parseInt(parentComputed.getPropertyValue("border-right-width"))

  }

  return { 
    left: pos.left - leftEdge, 
    right: rightEdge - pos.right 
  } 
}

There is one catch, you need to insert an empty <span></span> tag divider in between elements you are trying to compute the margins for. It can be any empty tag (which has 0 width and height, but visible).

<div id="parent">
  <div id="inner"></div>
  <span></span>
  <div id="other"></div>
</div>

If you were to remove the divider span tags, and use recursion to compute the previous and next element's margins you would run into circular infinite loop as left box would require the right box's left margin value and right box would require the left box's right margin value.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.