6

I have a <div> that's vertically centered with the following CSS:

.v-centered {
    position: relative;
    top: 50%;
    transform: translateY(-50%);
}

That's great as long as its height, which is not known beforehand, does not cause its translation to push it off the top off the screen in the case that the screen is too small.

I have some javascript (with jQuery) to mitigate this:

var $myDiv = $('#myDiv'),
    paddingTop = parseInt($('html').css('padding-top'));

window.onresize = () => {
    if ($myDiv.is('.v-centered')) {
        if ($myDiv.position().top < paddingTop) {
            $myDiv.removeClass('v-centered');
        }
    } else {
        if ($myDiv.height() < document.body.offsetHeight) {
            $myDiv.addClass('v-centered');
        }
    }
}

However, this is a bit ugly and, on the scale of resizing-a-window updating, is pretty slow. I'd love a pure CSS/HTML approach, or failing that, a window.onresize function that doesn't do so much calculation.

jsFiddle

dx_over_dt
  • 13,240
  • 17
  • 54
  • 102

1 Answers1

2

Instead of using the CSS positioning method for vertical centering, why not use flexbox, which can perform vertical centering with unknown, undefined or variable heights? Flexbox is pure CSS and you can scrap the JS.

To vertically center a child element with flexbox use:

.parent {
    display: flex;
    align-items: center;
}

In cases where the child element overflows the container, one more rule may be necessary to avoid a scrolling limitation.

.child {
    margin: auto;       /* for full vertical and horizontal centering */
 /* margin: auto 0; */  /* for vertical centering only */
 /* margin: 0 auto; */  /* for horizontal centering only */
}

DEMO

Learn more about vertical (and horizontal) centering with flexbox here:


Note that flexbox is supported by all major browsers, except IE 8 & 9. Some recent browser versions, such as Safari 8 and IE10, require vendor prefixes. For a quick way to add all the prefixes you need, post your CSS in the left panel here: Autoprefixer.

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • Here's a jsfiddle I used to test it... https://jsfiddle.net/wcw4d5sw/1/ It doesn't seem to fix my issue. The div just goes right off the top. – dx_over_dt Jan 18 '16 at 18:04
  • 1
    You need to add one more rule, for when the child element overflows the container. Answer revised. https://jsfiddle.net/wcw4d5sw/2/ – Michael Benjamin Jan 18 '16 at 18:10