6

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?

Ben Jackson
  • 11,722
  • 6
  • 32
  • 42
  • This may help: http://stackoverflow.com/questions/12718084/jquery-1-8-2-noncurrent-jquery-ui-outerwidth-and-outerheight-broken – Diodeus - James MacFarlane Jan 07 '14 at 17:09
  • @Diodeus I must be misunderstanding something because I'm not sure how that helps? I already knew about jQuery's `.outerWidth()` so had a look through their source, but it turns out it gives the wrong margin values in FF/Opera (at least in a flexbox) too. – Ben Jackson Jan 07 '14 at 20:27
  • There are other ways to find the margin - jquery has some powerful positioning functions that can help you compute it indirectly. Flexbox is still a relatively new concept in CSS and the support might not be as good as you expected. Why do you need the margins exactly? – ProfileTwist Jan 07 '14 at 22:16
  • @ProfileTwist the original problem has been solved using an alternative method. Now i'm just curious. – Ben Jackson Jan 08 '14 at 00:32

2 Answers2

3

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

Don Rhummy
  • 24,730
  • 42
  • 175
  • 330
  • @BYossarian can you please mark this as the answer so people can see this is what's happening? – Don Rhummy Jan 22 '14 at 17:18
  • It's `0px` for me in Chrome in 2022 though. The devtools show the brown margin but I can't get it's value in JS. – Nakilon Apr 29 '22 at 16:32
0

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.

cbayram
  • 2,259
  • 11
  • 9