Centrar elementos em CSS: na horizontal, na vertical, Flexbox e Grid

Três linhas de Flexbox para centrar uma div e depois cada caso à parte: horizontal, vertical, página inteira, imagem, texto, botão. Com a alternativa Grid, o método position absolute e os erros que impedem a centragem.

Centrar elementos em CSS com Flexbox: horizontal e vertical
Resposta rápida

Para centrar uma div dentro do seu contentor, dá ao contentor display: flex; justify-content: center; align-items: center;. justify-content centra na horizontal, align-items na vertical. Se a centragem vertical não se vir, é porque o contentor não tem altura: acrescenta min-height: 100vh para a página inteira, ou uma altura explícita.

Centrar uma div em CSS exigiu truques durante muito tempo. Já não é o caso: três linhas de Flexbox centram qualquer elemento dentro do seu contentor, na horizontal e na vertical. Este artigo começa por essa resposta curta e depois detalha cada situação, de uma imagem a um botão, com a alternativa Grid e os erros que fazem parecer que «não funciona».

A resposta curta

css
.conteneur {
  display: flex;
  justify-content: center; /* horizontal */
  align-items: center;     /* vertical */
}
html
<div class="conteneur">
  <div class="boite">Je suis centrée</div>
</div>

As duas propriedades põem-se no pai, nunca no elemento a centrar. E a centragem vertical só se vê se o pai tiver uma altura maior do que o seu conteúdo: é a primeira coisa a verificar quando nada se mexe.

Centrar na horizontal

Com Flexbox

justify-content distribui os filhos ao longo do eixo principal, horizontal por omissão. center agrupa-os no meio.

css
.conteneur {
  display: flex;
  justify-content: center;
  gap: 1rem; /* espaço entre vários filhos centrados */
}

Com vários filhos, ficam lado a lado, centrados em grupo. É o caso dos dois parágrafos ou das duas imagens do exemplo histórico deste artigo.

Com margin auto

Sem Flexbox, um bloco de largura conhecida centra-se com margens automáticas:

css
.boite {
  width: 320px;      /* ou max-width: indispensável */
  margin: 0 auto;
}

Sem width nem max-width, a caixa ocupa toda a largura disponível e as margens automáticas valem zero. É o método a reter para centrar uma coluna de conteúdo numa página.

Com text-align

text-align: center centra o conteúdo em linha de um bloco: texto, uma ligação, uma imagem inline. Não centra o próprio bloco dentro do pai.

css
.titre {
  text-align: center; /* centra o texto dentro de .titre */
}

Centrar na vertical

align-items trata do eixo transversal, vertical por omissão. O contentor tem de ter uma altura para que a centragem se veja.

css
.conteneur {
  display: flex;
  align-items: center;
  height: 300px;
}

Para centrar na vertical apenas um filho e deixar os outros em cima, align-self põe-se nesse filho:

css
.conteneur .dernier {
  align-self: center;
}

Outra escrita, muitas vezes mais curta: margin: auto no filho de um contentor flex centra-o nas duas direções, absorvendo todo o espaço livre.

css
.conteneur { display: flex; height: 300px; }
.boite     { margin: auto; }

Centrar em toda a página

Um ecrã de início de sessão, uma mensagem de erro, uma página de espera: o elemento tem de ficar no centro da janela. O contentor ocupa toda a altura visível com min-height: 100vh.

css
body {
  margin: 0;
}

.page {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh; /* 100% da altura da janela */
}

min-height em vez de height: se o conteúdo ultrapassar a janela num ecrã pequeno, o contentor cresce em vez de cortar. No telemóvel, 100dvh (altura dinâmica, que tem em conta as barras do navegador) é ainda mais exato e é suportado pelos navegadores atuais.

Centrar uma imagem

Uma imagem é um elemento em linha: dentro de um bloco, text-align: center no pai centra-a na horizontal. Para a centrar nos dois sentidos, ou dentro de uma moldura de tamanho fixo, o Flexbox é mais simples.

css
/* Só na horizontal */
figure {
  text-align: center;
}

/* Horizontal e vertical, numa miniatura quadrada */
.vignette {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 200px;
  height: 200px;
  overflow: hidden;
}

.vignette img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

Uma imagem sozinha numa coluna também se centra como bloco: display: block; margin: 0 auto; com uma largura ou uma largura máxima.

Centrar um texto e um botão

Um texto centra-se com text-align: center no seu bloco. Um botão é um elemento inline-block: a mesma propriedade no pai centra-o na horizontal.

css
.actions {
  text-align: center;
}

/* Para centrar vários botões com um espaçamento regular */
.actions {
  display: flex;
  justify-content: center;
  gap: 0.75rem;
}

Para centrar o texto dentro de um botão de altura fixa, o próprio botão passa a contentor flex: display: inline-flex; align-items: center; justify-content: center;.

A alternativa Grid: uma única linha

O CSS Grid centra um filho único numa só declaração:

css
.conteneur {
  display: grid;
  place-items: center; /* align-items + justify-items */
  min-height: 100vh;
}

Grid e Flexbox dão aqui o mesmo resultado. O Grid é mais curto para um só elemento; o Flexbox continua mais natural para alinhar uma fila de elementos. A escolha entre os dois modelos para uma disposição completa está detalhada em Grid ou Flexbox.

position absolute + transform: o caso das sobreposições

Quando o elemento a centrar está fora do fluxo, por exemplo um tooltip ou uma janela modal colocada por cima da página, posiciona-se a 50% e depois recua-se metade do seu próprio tamanho:

css
.parent {
  position: relative;
}

.modale {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

O método funciona sem se conhecer o tamanho do elemento, mas pode deixar o texto ligeiramente desfocado quando a translação cai em meio pixel. Para uma modal em ecrã inteiro, um contentor position: fixed; inset: 0; display: grid; place-items: center; evita o problema.

Porque «não funciona»: os cinco erros

  1. O pai não tem altura. A centragem vertical é relativa à altura do contentor; sem altura, não há nada para centrar. Acrescenta min-height.
  2. As propriedades estão no filho. justify-content e align-items vão no pai. No filho, só align-self e margin: auto atuam.
  3. margin: 0 auto sem largura. O bloco já ocupa 100%: dá-lhe uma width ou uma max-width.
  4. text-align: center para centrar uma div. Centra o texto lá dentro, não a caixa. Usa o Flexbox ou as margens automáticas.
  5. height: 100% que não faz nada. Uma percentagem de altura só vale se o pai tiver também uma altura definida, até ao html. 100vh ou 100dvh não dependem do pai.

Resumo

Quero centrar… Método
uma div nos dois sentidos pai display: flex; justify-content: center; align-items: center; (+ altura)
uma div na horizontal, sem Flexbox width + margin: 0 auto
um só filho, no mais curto pai display: grid; place-items: center;
em toda a página o mesmo + min-height: 100vh
uma imagem text-align: center no pai, ou Flexbox numa moldura
um texto ou um botão text-align: center no bloco pai
uma sobreposição (modal, tooltip) position: absolute; top/left: 50%; transform: translate(-50%, -50%)

Para ir além da centragem, o guia completo do Flexbox passa em revista todas as propriedades do contentor e dos filhos.

Erros frequentes

O contentor não tem altura align-items: center centra em relação à altura do contentor. Se esta for igual à do conteúdo, nada se mexe. Dá uma altura (min-height: 100vh, height: 300px) ao contentor.
Pôr as propriedades no filho justify-content e align-items põem-se no pai em display: flex, não no elemento a centrar. Só align-self e margin: auto se põem no filho.
margin: 0 auto sem largura Um bloco sem width nem max-width já ocupa toda a largura: as margens automáticas valem zero. Define uma largura.
text-align: center numa div Esta propriedade centra o conteúdo em linha (texto, imagens inline) dentro da div, não a própria div dentro do pai.

CSS

Damien Flandrin Programador web desde 2010, criador da Gekkode e do Email Impact. Cada artigo é testado num projeto real antes de ser publicado. Contacto
Newsletter

Os novos testes, tutoriais e projetos, por e-mail.

Testes reproduzíveis, código versionado, resultados datados. Nunca spam.