Centralizar usando CSS

Márcio d'Ávila, 10 de novembro de 2004. Revisão 2, 11 de maio de 2008.
Categoria: Internet: Cliente: DHTML

Centralizar blocos horizontalmente

Não existe em CSS1 ou CSS2 um estilo direto de alinhamento centralizado para a posição de elementos HTML de bloco, como DIV, P e TABLE, entre outros, que seja diretamente equivalente ao antigo atributo HTML align="center" (deprecado na especificações HTML 4 e XHTML 1 estritas).

Apresentamos aqui várias técnicas para centralização horizontal de blocos de forma implícita, envolvendo as propriedades CSS de largura, posição horizontal e margens esquerda e direita do bloco. A maioria das técnicas pode também ser aplicada à centralização vertical, fazendo uma equivalência com as propriedades de altura, posição vertical e margens superior e inferior do bloco, respectivamente.

Blocos com margem definida

Se a largura do bloco não for especificada e pudermos escolher o tamanho das margens, seja em uma unidade de medida absoluta (como pixels) ou relativa (como porcentual), definimos os estilos margin-left (margem esquerda) e margin-right (direita) do bloco com valores iguais para centralizá-lo. A largura do bloco centralizado ficará implicitamente definida como toda a largura restante entre suas margens:

margin-left: 10%; margin-right: 10%;
OK: Margens esquerda e direita iguais, usando unidade relativa.

O exemplo anterior usa unidade de medida relativa. A seguir, usando unidade absoluta:

margin-left: 50px; margin-right: 50px;
OK: Margens esquerda e direita iguais, usando unidade absoluta.

Blocos com largura definida

Largura porcentual (%)

Se tivermos um bloco com largura definida em valores porcentuais (em relação à largura total disponível na página), para centralizá-lo basta calcular a margem esquerda como metade da largura restante. Assim, se o bloco tem largura 80%, restam portanto 20% da largura total da página, que devem ser distribuídos em duas partes iguais. Definindo a margem esquerda do bloco como 10% (20 ÷ 2), por conseqüência teremos os 10% restantes equitativamente à sua direita. Desta forma, não é necessário um estilo definindo a margem direita.

Traduzindo a idéia em CSS, teremos o estilo width: 80%; margin-left: 10%; para o bloco. Este método funciona bem no Mozilla/Firefox testado (1.7/1.0), mas apresenta um problema no Internet Explorer (6 SP2). Veja o exemplo:

width: 80%; margin-left: 10%;
Problema: Largura resultante é 72% no Internet Explorer ≤ 6.

Bug: Neste exemplo, o Internet Explorer testado (6 SP2) primeiro aplica a a margem esquerda de 10% do bloco, e em seguida calcula sua largura como 80% do espaço restante da largura da página, já descontados os 10% do total usados na margem esquerda do bloco. Assim, o bloco tem 80% dos 90% restantes na largura da página, ou seja, 72% da largura total da página. Com isso, além de ficar com a largura incorreta, o bloco não fica centralizado, pois terá 10% da largura da página à sua esquerda e 18% à direita. O Internet Explorer 7 corrigiu o problema e exibe corretamente o bloco centralizado com 80% da largura total.

A centralização de bloco usando margens laterais baseia-se nas regras de posicionamento estático (static) padrão de um bloco. O mesmo princípio de centralizar "matematicamente" o bloco pode ser aplicado quando se usa posicionamento relativo (position: relative), definindo a posição esquerda (left), ao invés da margem. Para mais informações sobre os esquemas de posicionamento em CSS, veja a referência para a especificação de CSS2, apresentada ao final do texto. Veja o exemplo com posicionamento relativo do bloco e definição da sua posição esquerda left: 10%:

width: 80%; left: 10%; position: relative;
OK: Funciona nos navegadores Mozilla/Firefox e Internet Explorer.

Note que para blocos com largura percentual, podemos também aplicar o primeiro exemplo já visto para blocos com margem definida. A idéia é que se definirmos margens esquerda e direita 10%, estamos implicitamente definindo a largura do bloco em 80%.

Largura fixa

Quando a largura do bloco é definida com um valor fixo (em certa unidade de medida), podemos usar novamente o posicionamento relativo (position: relative) para colocar a posição do bloco no centro horizontal da página, definindo sua posição horizontal à partir da esquerda (left) como 50%. Veja o resultado deste primeiro passo, a seguir, onde o bloco ainda não está centralizado, mas sim posicionado ao centro (definimos este bloco com largura apenas 360px para que seja inteiramente vísível em resolução 800x600):

width: 360px; position: relative; left: 50%;
Passo 1: Posição esquerda no centro horizontal (50%).

Para efetivamente centralizar o bloco, precisamos fazer com que não sua lateral esquerda, mas sim seu centro horizontal, coincida com essa posição central. Para isso, recuamos o bloco à esquerda em metade da sua largura, definindo sua mergem esquerda negativa (- width/2). Por exemplo, para um bloco de largura 600 pixels, definimos sua margem esquerda como -300 pixels:

width: 600px; position: relative; left: 50%; margin-left: -300px;
OK: Posição esquerda no centro horizontal (50%), margem esquerda negativa em metade da largura do bloco (- width/2).

Outra técnica aplicável a blocos de largura fixa é o uso de margem automática, conforme o tópico adiante.

Margem automática

Ao invés de calcularmos manualmente o valor para as margens laterais do bloco, podemos usar o recurso de margem automática do CSS 2, usando o valor auto para ambas as margens esquerda e direita do bloco com largura definida:

width: 80%; margin-left: auto; margin-right: auto;
Problema: o Internet Explorer ≤ 6 não reconhece o valor auto e não centraliza o bloco.

Bug: o Internet Explorer até o 6 SP2 não reconhece o valor auto e simplesmente o ignora, de forma que o bloco não é centralizado e fica em sua posição padrão junto à margem esquerda da página. O Internet Explorer 7 corrigiu o problema e passou a reconhecer e tratar corretamente o auto.

Para contornar o bug do Internet Explorer 6, uma alternativa de centralização seria colocar o bloco dentro de outro, sendo que o bloco externo tenha estilo de texto centralizado (text-align: center). O Internet Explorer (7 inclusive) centraliza não só o texto, mas tem o efeito colateral de indevidamente centralizar também o bloco interno em si. Veja o exemplo de um bloco dentro de um DIV com estilo text-align: center.

width: 80%;
Problemas: O text-align: center do DIV externo só centraliza (indevidamente) o bloco interno no Internet Explorer. E o texto fica centralizado.

O efeito colateral inesperado do Internet Explorer, porém, não tem nenhum efeito no navegador Mozilla/Firefox, que corretamente mantém a posição do bloco interno à esquerda, centralizando apenas o texto dentro dele. Uma solução para se obter a centralização. Além disso, quando se deseja centralizar apenas o bloco, a centralização do texto dentro dele é um efeito indesejado.

Eis então como combinar os recursos vistos para contornar os problemas no Internet Explorer 6- e ao mesmo tempo garantir a centralização em navegadores que funcionam segundo o padrão: Para o Internet Explorer, colocar o bloco dentro de uma região com estilo text-align: center. Para anular o efeito do texto centralizado definido neste bloco externo, redefinir no bloco interno o estilo de volta para text-align: left. Para contemplar o Mozilla/Firefox e outros navegadores conformantes com o padrão, definimos também as margens esquerda e direita como auto. Como resultado temos:

DIV externo: text-align: center
width: 80%; text-align: left; margin-left: auto; margin-right: auto;
OK: Centraliza apenas o bloco tanto no Internet Explorer quanto no Mozilla/Firefox.

Se você não quiser suportar o Internet Explorer versão 6 e inferiores, basta utilizar o primeiro exemplo apresentado de margem automática, que funciona no Internet Explorer 7, Firefox e outros browsers mais atuais.

Blocos de largura variável

Vimos até agora técnicas de posicionamento quando ou a largura do bloco ou as margens laterais são especificadas. Mas a tabela (elemento TABLE) é um tipo particular de bloco que permite largura variável. Quando não é especificada uma largura arbitrária para uma tabela nem suas células, o navegador define sua largura automaticamente em função do conteúdo dentro da tabela.

Felizmente, a combinação de recursos aplicada no exemplo final da seção anterior, sobre margem automática, funciona igualmente bem para tabelas (TABLE) de largura automática, assim como para blocos de largura definida.

Para facilitar, vamos organizar os estilos utilizados na centralização em uma classe chamada "center", que deve ser simplesmente aplicada a um DIV englobando um ou mais blocos internos — DIV, P, TABLE, ou outro que você precise — com posição horizontal centralizada:

<style type="text/css">
div.center {
    text-align: center;
}
div.center div, div.center p, div.center table, div.center form {
    text-align: left; margin-left: auto; margin-right: auto;
}
</style>
<div class="center">
     bloco(s) ...
</div>

Veja exemplos, todos dentro de um DIV da classe "center", onde foi aplicado um fundo azul adicional para melhor visualização.

TABLE (tabela) de largura automática com duas células

DIV (divisão) de largura fixa, width: 500px;

P (parágrafo) de largura definida, width: 50%

FORM (formulário) com width: 500px

Referências


Firefox - A web de volta
Creative Commons License

© 2003-2010, Márcio d'Ávila, mhavila.com.br, direitos reservados. O texto e código-fonte apresentados podem ser referenciados, distribuídos e utilizados, desde que expressamente citada esta fonte e o crédito do(s) autor(es). A informação aqui apresentada, apesar de todo o esforço para garantir sua precisão e correção, é oferecida "como está", sem quaisquer garantias explícitas ou implícitas decorrentes de sua utilização ou suas conseqüências diretas e indiretas.