Blog ElCodiguero
13 Dec 2009 CSS

Centrado vertical con CSS

¿Cómo hacer para centrar verticalmente un bloque (div, párrafo, imagen, lo que sea) usando CSS?

En teoría (al menos así lo creo) debería bastar una variante del método que se usa para el centrado horizontal (especificar el ancho y luego poner tanto margin-left como margin-right a auto), pero no es así. Hacer eso simplemente no funciona. ¿Qué se debe hacer entonces para centrar un elemento de la página?

La verdad es que CSS lo hace un tanto difícil, sobretodo cuando antes bastaba con colocar valign="center" en un elemento para que se centrara con respecto a su padre. HTML 4 desaprobó los atributos align y valign (vertical align), por ser parte de la presentación visual, y por lo tanto ahora hay que centrar con CSS. Para colmo, la propiedad vertical-align de CSS no funciona como uno espera que lo haga, ya que de entrada se aplica solamente a elementos en línea y elementos con display:table-cell.

Hice algunas pruebas de varias técnicas en diferentes navegadores, y a continuacion presento los resultados.

Método 1

La forma más fácil, y la primera que se me ocurre, es fijar la altura del elemento, y repartir manualmente el resto de la altura de su contenedor entre los márgenes superior e inferior. Es decir, si el elemento tiene una altura de 90%, poner tanto margin-top como margin-bottom a 5% cada uno. En realidad no hace falta especificar las dos propiedades, basta con especificar el margen superior.

El problema con este método es que estira al elemento contenedor cuando el elemento interior no entra con su margen, y por lo tanto no es muy amigable a la hora de acomodar otras cajas en la página.

También es importante notar que si el margen especificado no alcanza para cubrir el 100% de la altura (por ejemplo, 70% de altura y 5% de margen), el elemento no queda centrado, aunque margin-top y margin-bottom sean iguales.

Por otro lado, si el elemento contenedor no es demasiado grande, puede centrarse el contenido unicamente especificando los márgenes, sin especificar la altura.

Por último, este método falla completamente si el contenedor tiene una altura fija, que no depende del contenido. A menos claro, que también esta altura sea conocida de antemano, ya que sabiendo este dato se pueden acomodar los márgenes para que quede centrado. Ver ejemplo del método 1.

Método 2

Una variante del anterior, que en vez de jugar con los márgenes usa el posicionamiento absoluto, y las propiedades top/bottom. Siguiendo el caso anterior, si el elemento tiene 90% de altura, poner top a 5% y bottom a 5% (o solamente top). Para el caso de elementos centrados verticalmente con respecto a otros elementos, el posicionamiento a elegir es relative en vez de absolute.

La particularidad de este método es que si crece el elemento padre, el elemento hijo (centrado) también crece. Esto implica que este método no falla como el anterior si el elemento contenedor tiene altura fija.

Puede ser útil para elementos con contenido variable, aunque en otros casos la pérdida de control sobre la altura del elemento centrado puede perjudicar al diseño. Ver ejemplo del método 2.

Método 3

El método más complejo y más preciso. Suponiendo que el elemento que se quiere posicionar tiene el id "centrado", el CSS necesario para centrarlo es:

 1  #centrado {
 2      position : absolute;
 3 
 4      /* se coloca el bloque a una distancia vertical al borde superior
 5      de la página igual a la mitad de la altura total de la misma. */
 6      top : 50%;
 7 
 8      /* se da la altura correspondiente al elemento */
 9      height : 400px;
10 
11      /* se especifica como margen superior la mitad de la altura del elemento */
12      margin-top : -200px;
13  }

Este método es el más adecuado para diseños complejos, ya que es muy específico en la ubicación del elemento con respecto a su elemento padre. Aunque el padre crezca, el hijo siempre queda centrado. Esto puede verse claramente en el ejemplo, centrando de esta manera se mantiene el control total sobre las medidas del bloque contenedor y del bloque contenido.

En mis pruebas este método funcionó en todos los navegadores, con un detalle: en ninguno de ellos funcionó con el margen superior especificado en porcentajes. Sí funcionó muy bien con medidas en píxeles y en em, pero no con porcentajes. De todas formas, dada la precisión en las medidas que requiere, creo que este no es un detalle muy importante. Ver ejemplo del método 3.

Otros métodos

Mikmoro, un verdadero experto en esto de jugar con CSS, ha recopilado (creado, investigado, se le han ocurrido) 3 métodos ligeramente diferentes para alinear un bloque verticalmente, utilizando la propiedad display de CSS, con el valor table-cell (celda de tabla). La particularidad de este valor de display es que hace que la propiedad vertical-align se comporte de forma similar a como uno espera que se comporte. Estos métodos están recopilados en el sitio: Recopilación de recursos CSS.

Conclusión

¿Cómo centrar verticalmente con CSS? es una de las preguntas más vistas en los foros sobre maquetación con CSS. Estos 3 métodos presentados no son nuevos, son métodos que todos hemos usado alguna vez. Intenté mencionar las ventajas y desventajas de cada uno, e intenté también ayudar en la decisión de cuál usar según el diseño que se quiera realizar. Si queda alguna duda de mis descripciones (que seguramente alguna quedará), creo que los ejemplos ayudan a disiparlas. De todas formas, los comentarios están abiertos.

¿Qué método usas?

Enlaces relacionados

Activa Javascript para para cargar los comentarios, basados en DISQUS

El Blog de ElCodiguero funciona sobre Pelican

Inicio | Blog | Acerca de