2

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

Frederick M. Rogers
  • 841
  • 4
  • 14
  • 37
  • Any reason you are doing this in JS, instead of using CSS to center elements? https://css-tricks.com/centering-css-complete-guide/, https://css-tricks.com/centering-in-the-unknown/ – CBroe Jan 19 '17 at 11:08
  • Indeed you can do this with CSS but this snippit is only a part of a larger plugin. The final product will recalculate widths and heights on the fly using the 'resize' event and % values as well as pixels. In addition i will be extending the code to use absolute positioning. The main problems is not working with widths, but heights as they tend to not respond too % values they way you want them too. ie. top or bottom margin/padding in % as well as height. – Frederick M. Rogers Jan 19 '17 at 12:58

1 Answers1

1

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>
ab29007
  • 7,611
  • 2
  • 17
  • 43