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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With