Sei que essa pergunta é antiga, mas descobri qual é a solução alternativa perfeita para mim.
Eu adiciono este css ao div que desejo centralizar:
div:before {
content: "";
display: inline-block;
height: 100%;
vertical-align: middle;
}
Isso funciona sempre e é limpo.
Edit: Apenas para fins de conclusão, eu uso scss e tenho um mixin útil que incluo em todos os pais que são filhos diretos que desejo centralizar verticalmente:
@mixin vertical-align($align: middle) {
&:before {
content: "";
display: inline-block;
height: 100%;
vertical-align: $align;
// you can add font-size 0 here and restore in the children to prevent
// the inline-block white-space to mess the width of your elements
font-size: 0;
}
& > * {
vertical-align: $align;
// although you need to know the font-size, because "inherit" is 0
font-size: 14px;
}
}
Explicação completa:
div:beforeadicionará um elemento dentro do div, mas antes de qualquer um de seus filhos. Ao usar :beforeou :afterdevemos usar uma content:declaração, caso contrário, nada acontecerá, mas para o nosso propósito, o conteúdo pode estar vazio. Em seguida, dizemos ao elemento para ser tão alto quanto seu pai, desde que a altura de seu pai seja definida e este elemento seja pelo menos inline-block. vertical-aligndefine a posição vertical de self em relação aos pais, ao contrário de text-alignque funciona de maneira diferente.
A @mixindeclaração é para usuários sass e seria usada assim:
div {
@include vertical-align(middle)
}