Centralizando com CSS - Um guia completo

visualizações Publicado em: 06/10/2014

Introdução

Crédito: essa matéria é uma tradução e foi escrita por Chris Coyer. URL do original: http://css-tricks.com/centering-css-complete-guide/. A tradução foi feita por James Clébio.

Centralizar coisas em CSS é o carro-chefe de dúvidas em CSS. Por que tem que ser tão difícil? Acho que a questão não é que seja algo difícil de se fazer, mas é que, havendo tantos métodos diferentes de se fazê-lo, dependendo da situação, fica difícil decidir qual método adotar.

Vamos conhecer esses métodos para facilitar na hora de decidir qual devemos usar.

Horizontalmente

Elemento inline ou inline-* (tipo texto ou link)

Você pode centralizar elementos inline horizontalmente em um elemento pai com apenas:

CSS

.filhos-centralizados {
	text-align: center;
}

Isto irá funcionar para elementos inline, inline-block, inline-table, inline-flex, etc.

Elemento block

Você pode centralizar um elemento block definindo sua margin-left e margin-right como auto (o elemento deve ter uma largura definida, caso contrário, sua largura seria 100% e não precisaria de centralização). Isso é feito normalmente com o seguinte código:

CSS

.centralizado {
	margin: 0 auto;
}

Mais de um elemento block

Se você tem dois ou mais elementos block que precisam ser centralizados horizontalmente em uma linha, o melhor a fazer é usar um display diferente. Aqui está um exemplo de como fazê-lo com inline-block e um exemplo usando flexbox:

Caso você tenha vários elementos block empilhados um sobre o outro, o ideal é usar a técnica de margem automática:

Verticalmente

Centralização vertical é um pouco mais complicado em CSS.

Elemento inline ou inline-* (tipo texto ou link)

Uma linha

Elementos inline/texto podem parecer centralizados verticalmente porque o espaçamento acima e abaixo deles é igual.

CSS

.link {
	padding-top: 30px;
	padding-bottom: 30px;
}

Se por algum motivo você não puder usar padding e está certo de que seu texto não terá quebra de linha, há um truque para centralizar seu texto verticalmente: defina o line-height igual a altura do container.

CSS

.texto-centralizado-truque {
	height: 100px;
	line-height: 100px;
	white-space: nowrap;
}

Múltiplas linhas

Espaçamento igual acima e abaixo pode dar o efeito centralizado em várias linhas de texto também, mas se isso não funcionar, provavelemente será porque o elemento de texto pode estar em um elemento tipo célula de tabela, literalmente ou feito para se comportar como tal via CSS. A propriedade vertical-align lida com isso, neste caso, ao contrário do que normalmente faz, que é lidar com o alinhamento de elementos em uma linha.

Se não for algo tipo tabela, talvez você possa usar flexbox; um único elemento filho pode centralizar em um elemento pai com bastante facilidade.

CSS

.flex-centralizado-verticalmente {
	display: flex;
	justify-content: center;
	flex-direction: column;
	height: 400px;
}

Lembre-se que isso só irá funcionar se o elemento pai tiver uma altura fixa (px, %, etc.), para que a altura o elemento filho seja relativa a altura do pai.

Se nenhuma dessas técnicas funcionarem, você pode usar a técnica de "elemento fantasma" *(ghost element)*, em que a altura total de um pseudoelemento é substituída dentro do container e o texto é verticalmente alinhado.

CSS

.fantasma-centralizado {
	position: relative;
}

.fantasma-centralizado:before {
	content: " ";
	display: inline-block;
	height: 100%;
	width: 1%;
	vertical-align: middle;
}

.fantasma-centralizado p {
	display: inline-block;
	vertical-align: middle;
}

Elemento block

Sabendo a altura do elemento

É bastante comum não saber a altura da página, por muitas razões: se a largura muda, a readaptação do texto no container pode alterar a altura. Variação no estilo do texto pode mudar a altura. Variação na quantidade de texto pode alterar a altura. Elementos com uma proporção fixa, como imagens, pode alterar a altura quando redimensionado. Etc.

Se souber a altura da página, você pode centralizar verticalmente fazendo o seguinte:

CSS

.pai {
  position: relative;
}

.filho {
	position: absolute;
	top: 50%;
	height: 100px;
	margin-top: -50px; /* account for padding and border if not using box-sizing: border-box; */
}

Elemento de altura desconhecida

É possível centralizar um elemento de altura desconhecida empurrando-o para baixo metade de sua altura e depois puxando-o para cima esse mesmo valor referenciado pelo seu eixo:

CSS

.pai {
	position: relative;
}
.filho {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
}

Flexbox

Centralizar verticalmente torna-se muito mais fácil quando se usa flexbox.

CSS

.pai {
	display: flex;
	flex-direction: column;
	justify-content: center;
}

Horizontalmente e verticalmente

Você pode combinar as técnicas acima para obter elementos perfeitamente centralizados.

Elemento com largura e altura fixos

Usando margens negativas iguais a metade da largura e altura, e depois posicionando o elemento de forma absoluta em 50%/50%, a centralização ocorrerá com boa compatibilidade entre os navegadores (*cross browser*):

CSS

.pai {
	position: relative;
}

.filho {
	width: 300px;
	height: 100px;
	padding: 20px;

	position: absolute;
	top: 50%;
	left: 50%;

	margin: -70px 0 0 -170px;
}

Elemento com largura e altura desconhecidos

Se você não sabe a largura ou a altura do elemento, você pode usar a propriedade transform e um translate negativo de 50% em ambas as direções (ele é baseado na largura/altura atual do elemento) para o centro:

CSS

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

Flexbox

Para centralizar em ambas as direções com flexbox, você precisa usar duas propriedades de centralização:

CSS

.pai{
	display: flex;
	justify-content: center;
	align-items: center;
}

Conclusão

Você pode centralizar as coisas com CSS!