Centrar verticalmente con CSS; 6 formas diferentes de lograrlo

Alineado vertical CSS @katharsix

A veces, por motivos de estética, nos viene bien alinear verticalmente un sitio web.

En los tiempos en que las webs se hacían con tablas, esto era sencillo gracias a la propiedad vertical-align de las mismas; pero con la aparición de las capas (Divs) y desaparición de las tablas esta propiedad murió.

Hoy traigo 6 formas diferentes de alinear una web verticalmente con CSS sin morir en el intento, totalmente validadas por el W3C y que dará ese toque que le falta a tu web.

Método con flexbox (más moderno y recomendado)

Este método es el más recomendado y fácil de implementar, basta con asignar al padre de nuestro html el siguiente código CSS:

<div class="padre">
   <div class="hijo">Contenido aquí.</div>
</div>
.padre {
   display: flex;
   align-items: center;
}

Con la propiedad justify-content: center hacemos que se centre horizontalmente, mientras que con align-items: center hacemos lo propio verticalmente. Cabe resaltar que estas propiedades sólo aplican en caso que el padre sea de mayor tamaño que el hijo. De hecho, si queremos que el hijo esté centrado en toda la pantalla deberemos asignarle esas dimensiones al padre.

Método del alto de linea (Line-height method)

Aunque es un método que sólo funciona con una línea de texto, puede ser útil para mostrar, por ejemplo, nuestro último tweet (muy de moda) en una única línea.

La forma de implementarlo sería la siguiente:

<div class="padre">
   <div class="hijo">Texto alineado aquí.</div>
</div>
.hijo {
   line-height: 200px; //Damos 200px de alto para notar el efecto
}

Y el resultado sería tal que así:

alinecion texto vertical @katharsix

Como véis le damos 200px por darle un valor, puede ser el que tú quieras. Yo he escogido esa medida para que se note bien el efecto.

Este método funciona en todos los navegadores, aunque es sólo aplicable a una línea de texto.

El método de la tabla CSS (CSS Table method)

Comentaba al principio de la entrada sobre el tiempo de las tablas y el posicionamiento vertical con vertical-align.

Este método se basa en eso, pero sin hacerlo con tablas como tal.

Lo que hacemos es tratar, mediante CSS, a una serie de capas como tablas HTML o celdas de tabla; con esto lograremos que el navegador vea dichas divs como tablas y podamos utilizar la propiedad vertical-align sobre ellas.

Debemos tener clara la idea de que las tablas CSS no son lo mismo que las tablas HTML.

La implementación sería así:

<div class="padre">
   <div class="hijo">Contenido centrado aquí.</div>
</div>
.padre {
   display: table;
   height:200px;
}
.hijo {
   display: table-cell;
   vertical-align: middle;
}

La explicación es más o menos lo que expliqué arriba; le otorgamos a la capa padre la propiedad display:table y a la capa hijo display:table-cell. Esto hará que la capa padre sea interpretada por el navegador como una tabla y la capa hijo como una celda de tabla.

A su vez, la capa hijo tendrá un vertical-align: middle para que se produzca el alineado vertical.

También tenemos en cuenta que en esta ocasión el alto de la capa va en el elemento padre.

Me gustaría advertir que este método no funciona por sí mismo en versiones antiguas de Internet Explorer, por lo que hay que «forzarlo» añadiendo un display:inline-block al elemento hijo.

El resultado:

CSS Table vertical align @katharsix

Posición absoluta y margen negativo (Absolute Positioning and Negative Margin)

Este método sólo funciona para elementos de tipo bloque (perfecto para las capas) y también funciona para todos los navegadores.

Implementación:

<div class="padre">
    <div class="hijo">Contenido centrado aquí.</div>
</div>
.padre {
   position: relative;
}
.hijo {
   position: absolute;
   top: 50%;
   left: 50%;
   height: 30%;
   width: 50%;
   margin: -15% 0 0 -25%;
}

Si nos fijamos en el CSS (El HTML no varía con los ejemplos anteriores) vemos que lo primero aplicamos un posicionamiento relativo a la capa padre y una posición absoluta al elemento hijo.

Después fijamos los valores top y left del elemento hijo al 50% (centro del elemento padre). Esto aún no es correcto.

Para que sea correcto necesitamos mover el elemento hijo hacia arriba (la mitad de su altura) y a la izquierda (la mitad de su ancho) para que lo que quede en el centro del elemento padre sea el centro del elemento hijo. Para esto necesitamos saber el tamaño de la capa (ancho y alto) y así poder restar el margen correspondiente.

Para hacer esto le damos un margen negativo al elemento hijo tanto superior como izquierdo igual a la mitad de su alto y su ancho respectivamente:

margin: -15% 0 0 -25%;

Tened en cuenta que habíamos dado un ancho del 50% y un alto del 30%, por eso el margen superior es del -15% (la mitad de 30) y el margen izquierdo es del -25% (mitad del ancho).

Como vais a poder ver en el demo, lo que centramos es una capa y no el texto en sí. Para esto habría que hacer otras técnicas que nos permitiesen centrarlo verticalmente. Nos hemos interesado en centrar la capa.

El resultado visible es:

alineacion vertical posicion absoluta y margen negativo @katharsix

Posición absoluta y extensión (Absolute Positioning and Stretch)

Tal y como hacíamos con el método anterior, vamos a aplicar una posición relativa al elemento padre y una absoluta al elemento hijo.

En el código que os muestro, utilizo el método para centrar tanto vertical como horizontalmente:

<div class="padre">
   <div class="hijo">Contenido centrado aquí.</div>
</div>
.padre {
   position: relative;
}
.hijo {
   position: absolute;
   top: 0;
   bottom: 0;
   left: 0;
   right: 0;
   width: 50%;
   height: 30%;
   margin: auto;
}

La idea de este método es intentar que el elemento hijo se centre indicando un top, bottom, right y left con valor 0.

Como el elemento hijo es más pequeño que su elemento padre no podrá alinear las 4 esquinas.

Indicando un margen automático a las 4 esquinas haremos que los márgenes opuestos (izquierda-derecha y arriba-abajo) sean iguales y mostrarán nuestra capa hijo en el centro del elemento padre.

¿Se entiende la idea?

Desgraciadamente, Internet Explorer 7 o inferiores nos juegan una mala pasada y no quiere mostrar nuestro CSS adecuadamente. Puede hacer que el contenido del elemento hijo crezca y termine por ocultarse.

El resultado final sería este:

alineacion vertical posicion absoluta y margen negativo @katharsix

Mismo padding superior e inferior (Equal Top and Bottom Padding)

En el anterior método le dejabamos al navegador la tarea de calcular automáticamente los márgenes del elemento hijo para que sus opuestos fueran idénticos.

En este método haremos algo similar, pero lo indicaremos nosotros.

<div class="padre">
   <div class="hijo">Contenido centrado aquí.</div>
</div>
.padre {
   padding: 5% 0;
}
.hijo {
   padding: 10% 0;
}

Con este CSS estamos especificando para ambos elementos (padre e hijo) el padding superior e inferior que deben tener.

Este método puede dar mucho juego si usamos medidas relativas para que se adapte automáticamente al alto de su contenido y demás, pero no es el tema de esta entrada. Realizaremos un ejemplo con medidas absolutas.

El resultado:

posicionamiento vertical css padding @katharsix

Div flotante (Floater Div)

Este último método requiere un div vacío que flota y se utiliza para controlar dónde se encuentra el elemento hijo dentro del documento. El elemento flotante viene antes que el elemento hijo en el documento HTML.

<div class="padre">
    <div class="floater"></div>
    <div class="hijo>Contenido aquí.</div>
</div>
.padre {
   height: 250px;
}
.floater {
   float: left;
   height: 50%;
   width: 100%;
   margin-bottom: -50px;
}
.hijo {
   clear: both;
   height: 100px;
}

Haremos que la capa flotante flote (valga la redundancia) a la izquierda (o derecha, da lo mismo) y le daremos un alto del 50% de su elemento padre. Esto hará que quede «ocupada» la mitad superior del elemento padre.

Como este elemento flotante es suprimido del flow normal del documento necesitamos limpiar el elemento hijo. De ahí que utilicemos clear:both, aunque realmente sólo necesitamos limpiar en el sentido que hicimos flotar la capa vacía.

La parte superior del elemento hijo quedará inmediatamente debajo de la parte inferior del elemento flotante. Necesitamos que el elemento hijo suba la mitad de su altura; para ello utilizamos un margen negativo como vimos anteriormente.

En esta ocasión el margen negativo lo aplicamos a la parte inferior de la capa flotante.

Este método funciona en todos los navegadores.

Resultado:

Alineacion vertical css div flotante @katharsix

Puedes ver todos los ejemplos en este codepen:

Fuente

¡MANTENME INFORMADO!

¡Gracias por tu interés en estar informado del próximo lanzamiento de mis cursos! 😎

¡No hago spam! Lee la política de privacidad para tener más información.

22 comentarios en “Centrar verticalmente con CSS; 6 formas diferentes de lograrlo

  1. Excelente artículo. Es bueno tener todas estas herramientas a mano en un mismo artículo.

    Por cierto, al final del último ejemplo dice «Este método funciona en todos los buscadores». Supongo que la última palabra del texto citado era «navegadores».

    ¡Saludos!

  2. Muy bueno como vemos a css le está faltando una propiedad para dicho fin, algo similar a text-align:center pero con estas alternativas se puede encarar igual

  3. Hola estoy haciendo una web en html5. Tengo un contenedor, dentro de él un section y dentro de él un div, como hago para que el alto de section se ajuste de acuerdo al contenido del div?? Gracias

  4. Hola

    Me pareció muy bueno tu articulo y además resolviste mi duda. Muchas gracias por ello.

    Si me pudieras recomendar algún libro que trate en profundidad de CSS te lo agradecería esto para fines de conocer más propiedades del lenguaje.

    Saludos.

  5. Muy buen artículo, me sirvió para solucionar un problema que tenía con un sitio de pruebas.

    No se si esté equivcado, pero según veo, parece que a la etiqueta no hay manera de centrarla verticalmente, pues seguí los pasos aquí indicados y no me funcionó, hasta que me decidí por cambiar el por un

  6. Buenísimo el siguiente ejemplo:


    #hijo {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    width: 50%;
    height: 30%;
    margin: auto;
    }

    Pero si no pones height y el width lo dejas en 100% + text-align center, el texto siempre quedará en el centro. Tal como así:


    #padre {
    position: relative;
    }
    #hijo {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%; /* Nuevo width */
    text-align: center; /* Texto centrado */
    margin: auto;
    }

    ¡Muchas gracias por abrirme los ojos!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*

*

DARÍO BALBONTÍN FERNÁNDEZ es el Responsable del tratamiento de los datos personales del usuario y le informa que estos datos serán tratados de conformidad con lo dispuesto en el Reglamento (UE) 2016/679 de 27 de abril (GDPR) y la Ley Orgánica 3/2018 de 5 de diciembre (LOPDGDD), por lo que se le facilita la siguiente información del tratamiento: Fin del tratamiento: mantener una relación comercial y el envío de comunicaciones sobre nuestros productos y servicios. Criterios de conservación de los datos: se conservarán mientras exista un interés mutuo para mantener el fin del tratamiento y cuando ya no sea necesario para tal fin, se suprimirán con medidas de seguridad adecuadas para garantizar la seudonimización de los datos o la destrucción total de los mismos.Comunicación de los datos: No se comunicarán los datos a terceros, salvo obligación legal. Derechos que asisten al usuario: Derecho a retirar el consentimiento en cualquier momento. Derecho de acceso, rectificación, portabilidad y supresión de sus datos y a la limitación u oposición al su tratamiento. Derecho a presentar una reclamación ante la Autoridad de control (agpd.es) si considera que el tratamiento no se ajusta a la normativa vigente. Datos de contacto para ejercer sus derechos: contacto@dariobf.com.