Margin percentages are always based on width.
Flexbox
You can achieve the desired effect with flexbox, as shown below.
/* Remember that containers' heights are a percentage of their parents' heights */
html, body {
padding: 0;
margin: 0;
height: 100%;
}
.container {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
h1 {
flex: 0 0 auto;
vertical-align: middle;
}
<div class="container">
<h1>Hello World</h1>
</div>
Alternative
Flexbox supports very complex scenarios, but there is an easier way for this particular case, using the vh
(viewport height) unit.
h1 {
font-size: 24px;
line-height: 32px;
margin-top: calc(50vh - 16px);
}
<h1>Hello World</h1>
Additional Note
I'm not sure why you used calc()
in your example, but if you do, be sure to put spaces around the operators. Spaces are not required for the division operator, but it's a good habit to get into.