Centering elements with margin/padding using .outerWidth()/.outerHeight(). Function returns different values for margin and padding

234 views Asked by At

i am attempting to center elements both laterally and vertically in their parent elements by calculating the difference in width and height of parent and child element and the using difference as either margin or padding.

I am calculating the necessary space using this formula:

($outerElement.outerWidth() - $innerElement.outerWidth() / 2;
($outerElement.outerHeight() - $innerElement.outerHeight() / 2;

I then loop over an array of directions using a function that allows me to change css applied to the child element using a function argument. Basically the function allows me to choose if i want to use margin or padding.

The Problem

While my code returns the expected values for top, right, left, and bottom it does not do so using padding? Any idea what is causing this?

HTML

<div id="demo" class="outer">
  <div class="inner">

  </div>
</div>

CSS

    html {
      box-sizing: border-box;
    }
    *, *:before, *:after {
      box-sizing: inherit;
    }

.outer {
      width:500px;
      height:200px;
      border:1px solid black;
      margin:20px;
    }

    .inner {
      width:100px;
      height:100px;
      background-color:grey;
    }

JAVASCRIPT

var $outer = $(".outer");
var $inner = $(".inner");

var getSpace = function(axis)  {

  if (axis.toLowerCase() == "x") {

    return ($outer.outerWidth() - $inner.outerWidth()) / 2;

  } else if (axis.toLowerCase() == "y") {

    return ($outer.outerHeight() - $inner.outerHeight()) / 2;

  }  

}

var renderStyle = function(spacingType) {

  $.each(["top", "right", "bottom", "left"], function(index, direction) {

    if (direction == "top" || direction == "bottom") {

      $inner.css(spacingType + "-" + direction, getSpace("y"));

      console.log(getSpace("y"));

    } else if (direction == "right" || direction == "left") {

      $inner.css(spacingType + "-" + direction, getSpace("x"));

      console.log(getSpace("x"));

    }                                     

  });                

}; 

renderStyle("padding");

CODEPEN LINK - link

1

There are 1 answers

1
ab29007 On BEST ANSWER

This is happening because you are setting padding to the inner box instead of the outer one.

You can set it using an if condition.

Here's the working snippet. You can test it for both renderStyle("margin"); and renderStyle("padding");

var $outer = $(".outer");
var $inner = $(".inner");

var getSpace = function(axis)  {
  if (axis.toLowerCase() == "x") {
    return ($outer.outerWidth() - $inner.outerWidth()) / 2;
  }
  else if (axis.toLowerCase() == "y") {
    return ($outer.outerHeight() - $inner.outerHeight()) / 2;
  }  
}

var renderStyle = function(spacingType) {
  var xi = getSpace("x");
  var yi = getSpace("y");
  if (spacingType == "padding") {
      var $ei = $outer;
  } else if (spacingType == "margin") {
      var $ei = $inner;
    } 
  $.each(["top", "right", "bottom", "left"], function(index, direction) {
    if (direction == "top" || direction == "bottom") {
      $ei.css(spacingType + "-" + direction, yi);
    }
    else if (direction == "right" || direction == "left") {
      $ei.css(spacingType + "-" + direction, xi);
    }                                     
  });                
}; 

renderStyle("padding");
.outer {
  width:400px;
  height:200px;
  border:1px solid black;
  margin:20px;
  box-sizing:border-box;
}
.inner {
  width:100px;
  height:100px;
  background-color:grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="demo" class="outer">
  <div class="inner">
  </div>
</div>