Programação Por Equipe DevBras

Capa do artigo: vertical-align não centraliza div: onde ele funciona e o que usar no lugar

vertical-align não centraliza div: onde ele funciona e o que usar no lugar

vertical-align só age em elementos inline e células de tabela. Veja o que ele faz de verdade, como usar para alinhar ícone e texto, consertar o vão embaixo da imagem e centralizar bloco com flex ou grid.

Quinta, 16h. O card de "Pagamento pendente" precisa do texto no meio da caixa de 120 pixels. Você escreve vertical-align: middle na div, recarrega, e o texto continua grudado no topo. Põe !important, testa vertical-align: center, e nada. A tarde vai embora brigando com uma propriedade que nunca foi feita para isso.

A resposta curta: vertical-align só funciona em elementos inline, inline-block e células de tabela. Numa div comum, que é display: block, ele é ignorado. Para centralizar um bloco dentro de outro, use display: flex com align-items: center ou display: grid com place-items: center no pai. Guarde vertical-align para o que ele faz bem: alinhar ícone com texto na mesma linha e alinhar conteúdo em célula de tabela.

O que vertical-align faz de verdade

O nome engana. A propriedade não alinha um elemento dentro do pai. Ela alinha um elemento inline em relação à linha de texto em que ele está. Pense numa linha de caderno: as letras se apoiam numa linha de base, algumas descem abaixo dela (g, p, q), outras sobem (as maiúsculas, o l, o h). Um ícone, uma imagem ou um span no meio dessa linha precisa de uma regra para saber onde se apoiar. Essa regra é o vertical-align.

Os valores mais usados:

  • baseline (padrão): a base do elemento fica na linha de base do texto. Para imagem, a base é a borda de baixo.
  • middle: o meio do elemento fica na linha de base do pai mais metade da altura da letra x minúscula. É "meio da letra minúscula", não "meio da caixa".
  • top e bottom: alinham com o topo ou o fundo da linha inteira.
  • text-top e text-bottom: alinham com o topo ou o fundo da fonte do pai.
  • sub, super e comprimentos como -0.125em: sobem ou descem o elemento em relação à base.

Em célula de tabela, o significado muda: ali top, middle e bottom posicionam o conteúdo dentro da célula. É por isso que tutoriais antigos, como o que originou este post, ensinavam a transformar a div em display: table-cell para centralizar. Funcionava, mas era um desvio para contornar a falta de ferramenta melhor. Hoje a ferramenta existe.

Em elemento de bloco e em item de flex ou grid, a propriedade não se aplica. O navegador aceita a declaração, não reclama, e não faz nada. As ferramentas de desenvolvedor do Firefox e as versões recentes do Chrome costumam marcar a declaração como sem efeito, com uma dica do motivo.

Como centralizar o card do jeito certo

O card de "Pagamento pendente" tem altura fixa de 120 pixels e um parágrafo dentro. A correção vai no pai, não no texto:

  1. Abra o inspetor, selecione o elemento que você quer mover e veja o display calculado.
  2. Identifique o pai, que é quem tem a área onde o filho deve ficar centralizado.
  3. No pai, aplique flex ou grid com alinhamento no eixo vertical.
  4. Remova o vertical-align, o line-height gigante e o margin-top calculado na mão que sobraram das tentativas.
<div class="card-aviso">
  <p>Pagamento pendente</p>
</div>
/* centraliza na vertical */
.card-aviso {
  display: flex;
  align-items: center;
  min-height: 120px;
  padding: 0 16px;
}

/* centraliza nos dois eixos */
.card-aviso--meio {
  display: grid;
  place-items: center;
  min-height: 120px;
}

Use min-height em vez de height: se o texto quebrar em três linhas no celular, o card cresce em vez de vazar. Nos navegadores atuais, desde 2024, também existe align-content: center em blocos comuns, sem mudar o display. Se o seu público usa navegador antigo, flex e grid são a aposta segura. Para os detalhes de centralizar nos dois eixos sem número mágico, inclusive com texto de tamanho variável, veja o guia de centralizar um bloco na horizontal e na vertical.

Onde vertical-align é a ferramenta certa

Ícone ao lado do texto

Agora o card ganha um ícone de alerta antes da frase. Os dois são inline, estão na mesma linha, e o ícone aparece um pouco acima ou abaixo do texto. Aqui sim:

<p class="aviso">
  <img src="/icones/alerta.svg" width="20" height="20" alt="">
  Pagamento pendente
</p>
.aviso img {
  vertical-align: middle;
}

/* alternativa: descer o ícone um pouco abaixo da base */
.aviso img.ajuste-fino {
  vertical-align: -0.125em;
}

O middle resolve na maioria das fontes. Quando o ícone tem o mesmo tamanho da fonte, um deslocamento pequeno em em costuma ficar mais preciso, porque acompanha o tamanho do texto. Se o card já é flex, outra saída é deixar o align-items: center do pai alinhar ícone e texto como dois itens. O alt="" vazio diz ao leitor de tela que o ícone é decorativo, porque a frase ao lado já informa tudo.

O vão misterioso embaixo da imagem

A foto do produto fica dentro de uma div com borda, e aparecem uns 4 pixels de espaço entre a imagem e a borda de baixo. Ninguém pôs margem. A causa é o baseline: a imagem é inline, apoia a borda de baixo na linha de base do texto, e o espaço abaixo da base fica reservado para as letras que descem. Duas correções, ambas de uma linha:

.foto-produto img { display: block; }
/* ou */
.foto-produto img { vertical-align: top; }

Célula de tabela de verdade

Numa tabela de dados com linhas de alturas diferentes, td { vertical-align: top; } faz o texto curto começar alinhado com o início do texto longo da célula vizinha, o que facilita a leitura. Esse é o uso original da propriedade, e continua correto.

Erros comuns

  • Aplicar vertical-align numa div de bloco. A declaração é ignorada sem erro, e você perde tempo achando que o problema é especificidade.
  • Usar vertical-align: center. Esse valor não existe; o navegador descarta a declaração inteira.
  • Colocar a propriedade no filho de um flex. Item de flex não obedece vertical-align; quem alinha é o align-items do pai ou o align-self do item.
  • Centralizar com line-height igual à altura da caixa. Funciona com uma linha só e quebra no primeiro texto que pula para a segunda.
  • Transformar tudo em display: table-cell. Resolve o centro e cria efeitos colaterais de largura e de margem que ninguém entende depois.
  • Calcular margin-top na mão. O número mágico só vale para aquela fonte, aquele texto e aquela tela.

Checklist

  • Você conferiu no inspetor o display do elemento antes de mexer no alinhamento.
  • Centralização de bloco é feita no pai, com flex ou grid.
  • A caixa usa min-height, não height fixa, quando o texto pode crescer.
  • vertical-align aparece só em elementos inline, inline-block ou células de tabela.
  • Ícones ao lado de texto estão alinhados com middle ou um deslocamento em em.
  • Imagens dentro de caixas com borda não deixam vão embaixo.
  • Restos de tentativas antigas (!important, margens calculadas) foram removidos.

Se o botão do card também tem ícone, vale ler sobre ícone com nome no botão para não perder a acessibilidade junto com o alinhamento. E antes de escrever a próxima regra de alinhamento, abra o inspetor e responda: o elemento que você quer centralizar é inline, bloco comum ou item de flex?

Avalie este artigo

Referência: http://www.maujor.com/blog/2006/07/17/propriedade-vertical-align/