3 formas de centralizar qualquer elemento em CSS
Tags: css, elemento, centralizar, alinhar
Published: 2022-07-11 20:23:01

## Para centralizar em CSS, existem três cenários clássicos que você enfrenta. Veja como chegar na interface desejada usando text-align, display flex, display grid, position relative e position absolute.
 
Sem tempo, irmão?
 
Tenta isso daqui:
 
```css
.elemento-pai {
  display: flex;
  justify-content: center;
  align-items: center;
}

.elemento-filho {
  /* nothing */
}
```
 
Se não resolver (e para entender o porquê das coisas), segue a leitura ;)
 
Para centralizar em CSS, você deve estar em um desses três cenários:
 
- <p>Centralizar elementos de texto</p>
- <p>Centralizar imagens ou blocos (como `divs`)</p>
- <p>Ou alinhar no sentido horizontal e/ou vertical</p>
 
Veja agora como tratar cada um dos casos.
 
## Centralizar em CSS: elementos de texto
 
Esse é o caso mais simples, basta você usar a propriedade `text-align: center`.
 
Apesar da propriedade começar com a palavra **text**, os elementos inline, como `span` ou `strong`, não sofrem nenhuma alteração. Essa propriedade muda apenas o conteúdo de elementos que possuem o `display` padrão como `block`, tal como `p`, `div` e `section`.
 
Para alinhar ao centro uma imagem usando `text-align`, coloque essa propriedade em um elemento `block`, como uma `div`, e coloque a imagem dentro dela.
 
Isso funciona porque a propriedade `text-align` é herdada pelos elementos filhos. Veja esse exemplo:
 
```html
﻿<div class="container">
  <h1>Centralizar em CSS</h1>
  <p>Uma hora a gente aprende...</p>
  <img src="https://unsplash.it/300?image=999" alt="breakfast">
</div>
```
 
```css
.container {
  text-align: center;
  
  border: 1px solid;
}
```
 
Nesse exemplo, o título, o parágrafo e a imagem ficam centralizados, pois eles herdam o estilo do elemento pai `div.container`.
 
![Centralizar elementos com text-align](https://www.datocms-assets.com/64896/1649804865-1.png)
 
Você pode usar outra forma para centralizar imagens e também elementos de bloco. Veja abaixo:
 
## Como centralizar imagens, divs e outros elementos em CSS
 
Existem duas formas de centralizar elementos de bloco:
 
1. <p>Aplicando estilo no próprio elemento</p>
2. <p>Aplicando estilo no elemento pai</p>
 
Cada método tem suas vantagens e desvantagens, e você precisa analisar para entender qual é a melhor na sua situação.
 
Uma regra que você sempre deve ter em mente é que, para que um elemento seja centralizado na horizontal, a sua largura deve ser menor que a largura do elemento pai. Veja o exemplo abaixo:
 
```html
<div class="gallery">
  <img
    src="https://unsplash.it/300?image=999"
    alt="breakfast"
    class="image"
    alt="A gallery image"
  />
</div>
```
 
```css
.gallery {
  width: 100%; /* isso é padrão para elementos div */
  
  border: 1px solid;
}

.gallery .image {
  width: 80%; /* usei 80% como exemplo, porém vale qualquer valor abaixo de 100% */
}
```
 
Veja agora como centralizar o elemento `.image` aplicando propriedades CSS apenas nele:
 
### Aplicando estilo no próprio elemento
 
Nesse exemplo de uma galeria de imagens, vou centralizar a única imagem que existe.
 
Se você prestou atenção à regra da largura mencionada acima, apenas coloque `margin: auto` nas laterais da imagem:
 
```css
.gallery {
  width: 100%;
}

.gallery .image {
  width: 80%;
  display: block; /* Necessário para o margin funcionar */
  margin-left: auto; /* aqui */
  margin-right: auto; /* e aqui */
}
```
 
Ou use um shorthand:
 
```css
.gallery {
  width: 100%;
}

.gallery .image {
  width: 80%;
  display: block;
  margin: 0 auto; /* zero para top e bottom, e auto para as laterais */
}
```
 
Esse shorthand só funcionará, caso a margem superior e inferior do elemento seja 0. Caso contrário, coloque outro valor no lugar de zero, ou defina as margens laterais em propriedades separadas.
 
![Centralizar imagem usando margin auto](https://www.datocms-assets.com/64896/1649817943-2.png)
 
Mas existe uma forma de centralizar elementos sem aplicar nenhuma propriedades neles:
 
### Aplicando estilo no elemento pai
 
Para isso, você precisa do recurso CSS mais amado dos últimos anos (quem não gosta dele, está errade): o **Flexbox**.
 
Recomendo esse modo quando você já está trabalhando em uma seção com `display: flex`:
 
```css
.gallery {
  display: flex;
  flex-direction: row; /* row é padrão */
  justify-content: center;
}
```
 
Na maioria dos casos isso basta, e nada precisa ser feito no elemento filho `.image`.
 
Nesse exemplo, a propriedade `justify-content: center` está centralizando a imagem, porque o `flex-direction` padrão é `row`.
 
Caso a direção seja mudada para `column`, você precisará centralizar os elementos usando `align-items`, e não mais `justify-content`, veja:
 
```css
.gallery {
  display: flex;
  flex-direction: column;
  align-items: center;
}
```
 
Como você deve ter desconfiado, `justify-content` e `align-items` alinham tanto na vertical, quanto na horizontal. Tudo depende da direção (`flex-direction`) do Flexbox. 
 
## Centralizar em CSS: sentido vertical e horizontal
 
A regra que falei no capítulo anterior sobre o sentido horizontal continua valendo. Mas agora na vertical: para que um elemento seja centralizado verticalmente, a sua altura deve ser menor que a altura do elemento pai.
 
### Display Flex
 
Está lembrado das propriedades de alinhamento do Flexbox? Agora vou usar as duas em conjunto:
 
```css
.gallery {
  display: flex;
  justify-content: center; /* Alinhamento horizontal */
  align-items: center; /* Alinhamento vertical */
  width: 100%;
  height: 300px;
}

.gallery .image {
  width: 40%;
  height: 150px;
}
```
 
![Centralizar imagem na vertical e horizontal usando display flex](https://www.datocms-assets.com/64896/1649817988-3.png)
 
As propriedades aplicadas em `.image` servem apenas para que ela seja menor do que o elemento pai.
 
Aqui, caso o `flex-direction` fosse `column`, nada mais precisaria mudar. A única diferença é que as propriedades de alinhamento teriam suas funções trocadas:
 
```css
.gallery﻿ ﻿{﻿
  ﻿display﻿:﻿ flex﻿;
  ﻿flex-direction: column; /* Mudou a direção */﻿
  ﻿justify-content﻿:﻿ center﻿;﻿ ﻿/* Agora, alinhamento vertical */﻿
  ﻿align-items﻿:﻿ center﻿;﻿ ﻿/* e alinhamento horizontal */﻿
  ﻿width﻿:﻿ ﻿100﻿%﻿;﻿
  ﻿height﻿:﻿ ﻿300﻿px﻿;﻿
﻿}﻿

﻿.gallery﻿ ﻿.image﻿ ﻿{﻿
  ﻿width﻿:﻿ ﻿40﻿%﻿;﻿
  ﻿height﻿:﻿ ﻿150﻿px﻿;﻿
﻿}
```
 
### Display Grid
 
Muito semelhante ao exemplo anterior:
 
```css
.gallery {
  display: grid;
  place-items: center; /* Alinhamento horizontal e vertical */
  width: 100%;
  height: 300px;
}

.gallery .image {
  width: 10%;
  height: 30px;
}
```
 
### Position Absolute
 
A técnica do `position: absolute` é muito usada quando você quer posicionar um texto sobre uma imagem:
 
```html
<div class="container">
  <img
    src="https://unsplash.it/300?image=999"
    alt="breakfast"
    class="image"
  />
  <p class="text">Café da manhã</p>
</div>
```
 
Para começar, aplique a propriedade `position`:
 
```css
.container {
  position: relative;
}

.container .image {
  display: block;
  width: 100%;
}

.container .text {
  position: absolute;
  z-index: 1;
}
```
 
Simples assim:
 
- <p>`relative` no pai</p>
- <p>`absolute` no filho</p>
 
A propriedade `z-index: 1` serve apenas para garantir que o texto não ficará por baixo da imagem. Caso haja outros elementos com `position: absolute`, use o `z-index` para controlar a ordem de cada elemento na pilha.
 
As propriedades colocadas na imagem servem apenas para ela ocupar todo o espaço do container.
 
Mas o texto ainda não está por cima da imagem. O que falta? Falta informar qual será sua posição:
 
- <p>Para o sentido vertical, use `top` ou `bottom`;</p>
- <p>Para o sentido horizontal, use `left` ou `right`;</p>
 
```css
.container {
  position: relative;
}

.image {
  display: block;
  width: 100%;
}

.text {
  position: absolute;
  z-index: 1;
  top: 50px; /* 50px de distância do topo */
  left: 25px; /* 25px de distância da esquerda */
  
  background-color: white;
  padding: 1rem;
}
```
 
A leitura padrão do HTML é **um elemento após o outro**. Mas dessa forma que expliquei, o elemento posicionado (no caso o texto) ficará **por cima** dos outros elementos irmãos.
 
![Posicionar texto sobre imagem usando position](https://www.datocms-assets.com/64896/1649818040-4.png)
 
Além disso, ele ficará "preso" dentro do elemento com `position: relative` (nesse exemplo, o `.container`). 
 
Para que o texto fique realmente centralizado, faltam 2 etapas.
 
Primeiro, troque os valores de `top` e `left` para `50%` (isso quer dizer a metade do container). Assim você vai perceber que o texto está "quase centralizado". Isso acontece porque o que está centralizado não é o ponto central do texto, e sim o ponto superior esquerdo dele.
 
![Posicionar texto sobre imagem usando position (está quase)](https://www.datocms-assets.com/64896/1649818078-5.png)
 
E assim você acaba de chegar à última etapa que é mover o ponto do elemento que realmente é posicionado:
 
```css
.container {
  position: relative;
}

.image {
  display: block;
  width: 100%;
}

.text {
  position: absolute;
  transform: translate(-50%, -50%); /* tcharaaaaaannnnn */
  z-index: 1;
  top: 50%;
  left: 50%;
  
  background-color: white;
  padding: 1rem;
}
```
 
![Posicionar texto sobre imagem usando position (agora sim!)](https://www.datocms-assets.com/64896/1649818115-6.png)
 
O `transform` movimenta esse ponto focal para onde você quiser. Agora, nada mais arranca seu texto do centro 😎
 
Uma alternativa ao `position: absolute` é usar `display: grid`.
 
### Display Grid
 
Olha ele aí de novo.
 
Enquanto no `position: absolute` permite um controle maior com medidas em px ou %, o `display: grid` vai permitir usar apenas valores como `start`, `center` e `end` . Dependendo do seu caso, isso pode ser o suficiente, então sempre analise do que você precisa.
 
Vou pegar o mesmo exemplo do HTML anterior:
 
```html
<div class="container">
  <img
    src="https://unsplash.it/300?image=999"
    alt="breakfast"
    class="image"
  />
  <p class="text">Café da manhã</p>
</div>
```
 
Para começar a sobrepor os elementos, veja esta magia:
 
```css
.container {
  display: grid;
}

.container > * {
  grid-area: 1 / -1;
}

.container .text {
  background-color: white;
  padding: 1rem;
}
```
 
Isso transforma o container em um grid. Em seguida, o `grid-area: 1 / -1` faz os filhos de primeiro nível do container começarem na primeira linha e primeira coluna (`1`), e terminarem na última linha e última coluna (`-1`) desse grid.
 
Ou seja, todos eles ficam dentro da mesma (e única) célula do grid.
 
Preste atenção à ordem dos elementos HTML, como o texto está depois a imagem, ele ficará por cima dela. Você também pode usar o `z-index` para controlar a ordem deles nessa pilha.
 
E como posicionar o texto sobre a imagem agora? Ele deve receber duas propriedades:
 
- <p>Alinhamento horizontal: `justify-self` com os valores `start`, `center` ou `end`</p>
- <p>Alinhamento vertical: `align-self` também com os mesmos valores `start`, `center`, ou `end`</p>
 
Por exemplo, para posicionar o texto à direita e ao meio da imagem, o código fica assim:
 
```css
.container .text {
  justify-self: end;
  align-self: center;
  
  background-color: white;
  padding: 1rem;
}
```
 
![Posicionar texto sobre imagem usando display grid. Texto alinhado à direita e ao meio da imagem](https://www.datocms-assets.com/64896/1649818145-7.png)
 
Caso você queira que o texto fique na parte de baixo e à esquerda:
 
```css
.container .text {
  justify-self: left; /* opcional, pois é o valor padrão */
  align-self: end;

  background-color: white;
  padding: 1rem;
}
```
 
![Posicionar texto sobre imagem usando display grid. Texto alinhado à esquerda e no bottom da imagem](https://www.datocms-assets.com/64896/1649818195-8.png)
 
O que achou dessas formas de centralizar em CSS?
 
## Callback
 
Em resumo, veja que tipo de conteúdo você precisa centralizar:
 
- <p>Elementos textuais</p>
- <p>Imagens, divs e outros elementos de bloco</p>
- <p>Alinhamento vertical/horizontal</p>
 
As principais propriedades CSS para centralizar envolvem:
 
- <p>`text-align`</p>
- <p>`display: flex`</p>
- <p>`display: grid;`</p>
- <p>`position: relative` e `position: absolute`</p>
 
Dúvidas? Deixe nos comentários, e vamos codar.