Articles

13 formas de centrar verticalmente

Posted on

En los buenos tiempos, los límites de CSS eran tales que incluso cosas «sencillas» como el centrado vertical suponían un reto, y algunos de nosotros incluso confiábamos en soluciones de JavaScript. Era frágil, estaba muy restringido, y siempre había esa excepción que lo hacía fallar.

Ya sea que estuviéramos tratando de alinear un icono o una imagen junto al texto, crear uno de esos populares banners «héroe», o una superposición modal, centrar las cosas en el eje vertical era siempre una lucha.

Pero CSS ha recorrido un largo camino desde entonces, proporcionando un montón de métodos que hicieron que el centrado vertical fuera cada vez más fácil. Aquí hay un resumen de algunos de ellos, junto con sus casos de uso y limitaciones.

Posicionamiento absoluto y margen automático

Un elemento sin tamaño intrínseco puede ser «centrado» simplemente usando valores iguales de la parte superior e inferior. Cuando el elemento tiene dimensiones intrínsecas podríamos usar 0 para la parte superior e inferior, y luego aplicar margin auto. Esto centrará automáticamente el elemento:

.container{ position:relative;}.element{ position:absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; height: 20px; /*requires explicit height*/}

Ver el Pen
Centering 1: absolute positioning por Facundo Corradini (@facundocorradini)
en CodePen.

La limitación es, por supuesto, que la altura del elemento debe ser declarada explícitamente, o ocupará todo el contenedor.

El clásico top 50% translate -50%

Este es uno de los primeros, y todavía un go-to, para muchos desarrolladores. Un truco sencillo, que se basa en posicionar de forma absoluta el elemento interior al 50% de la parte superior de su padre, y luego traducirlo hacia arriba el 50% de su altura:

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

Ver el Pen
Centering 2: top 50 translateY -50 por Facundo Corradini (@facundocorradini)
en CodePen.

Un enfoque bastante sólido, con la única limitación importante del uso de translate que podría estorbar a otras transformaciones, por ejemplo, al aplicar transiciones/animaciones.

Tablas. Sí, acabo de decir tablas.

Un enfoque realmente sencillo y uno de los primeros (en su día, todo eran tablas), es utilizar el comportamiento de las celdas de la tabla y el alineamiento vertical para centrar un elemento en el contenedor.

Esto se puede hacer con tablas reales (vergüenza, vergüenza, vergüenza), o usando HTML semántico, cambiando la visualización del elemento a tabla-celda:

.container{ display: table; height: 100%;}.element{ display: table-cell; text-align: center; vertical-align: middle;}

Ver el Pen
Centering 3: tables por Facundo Corradini (@facundocorradini)
en CodePen.

Esto funciona incluso cuando ambos elementos son de altura desconocida. La mayor limitación es, por supuesto, si necesitas tener un hermano no centrado, y puede ser complicado con los límites del fondo.

También hay que tener en cuenta que esto falla totalmente en los lectores de pantalla (incluso si tu marcado está basado en divs, establecer el CSS display a table y table-cell hará que los lectores de pantalla lo interpreten como una tabla real). Lejos de lo mejor en cuanto a accesibilidad.

El método del elemento fantasma

Otro viejo método, que no se puso al día por alguna razón, es usar inline-block con un elemento fantasma (pseudo) que tiene el 100% de la altura del padre, y luego establecer la propiedad de alineación vertical al centro:

.container::before { content: ''; display: inline-block; height: 100%; vertical-align: middle; margin-left: -1ch;}.element{ display: inline-block; vertical-align: middle;}

Ver el método Pen
Centering 4: ghost element por Facundo Corradini (@facundocorradini)
en CodePen.

La verdad es que funciona bastante bien, siendo el «gotcha» más notorio que mueve el centro horizontal un poquito a la derecha, por el comportamiento siempre cutre de los espacios en blanco entre elementos inline-block.

Esto puede ser tratado como lo haríamos con el problema de inline-block en cualquier otro contexto, el enfoque más simple es el margin-left -1ch que he utilizado anteriormente (aunque esto no será 100% preciso, excepto en las fuentes monospace, ya que la unidad ch significa el ancho del carácter «0»), o establecer el tamaño de la fuente a 0 en el contenedor y luego restablecerlo a px o rem en el elemento. No es óptimo, por decir algo.

Margen automático en un elemento flex

Por fin entrando en territorio CSS moderno, flexbox introdujo un comportamiento bastante impresionante para los márgenes automáticos. Ahora, no sólo centrará horizontalmente el elemento como lo hacía en los diseños de bloque, sino que también lo centrará en el eje vertical:

.container{ display:flex;}.element{ margin:auto;}

Veamos el Pen
Centering 5: margin:auto on a flex-item por Facundo Corradini (@facundocorradini)
en CodePen.

Esta táctica es una de mis favoritas por su simplicidad, la única limitación importante es que sólo funcionará con un solo elemento.

Pseudoelementos sobre un flex-container

No es el enfoque más práctico del mundo, pero también podemos utilizar pseudoelementos flexibles y vacíos para empujar el elemento al centro:

.container{ display:flex;}.element{ margin:auto;}

Ver el Pen
Centering 6: pseudos en un flexbox por Facundo Corradini (@facundocorradini)
en CodePen.

Esto puede ser útil cuando queremos mantener un espaciado flexible en un flexcontainer orientado a columnas con múltiples elementos.

7 & 8. Alinear en el flex-container o en el flex-item

Flexbox también introdujo propiedades de alineación realmente buenas (que ahora se bifurcan en su propio módulo de alineación de cajas). Esto nos permite controlar cómo se colocan los elementos y cómo se distribuye el espacio vacío de maneras que habrían requerido o bien números mágicos en CSS para un número específico de elementos (o un JS bastante inteligente para cantidades dinámicas).

Dependiendo de la dirección de flexión, podríamos usar justify-content o align-items para ajustar según sea necesario.

En el contenedor:

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

Ver el Pen
Centering 7: align on flex-container por Facundo Corradini (@facundocorradini)
en CodePen.

Sobre un flex-item particular:

.container{ display: flex;}.element{ align-self: center; margin: 0 auto;}

Ver el Pen
Centering 8: align on flex-item by Facundo Corradini (@facundocorradini)
en CodePen.

No hay muchas desventajas en esto, excepto si necesitas soportar navegadores antiguos. IE 11 debería funcionar, pero su implementación de flexbox tiene bastantes fallos, por lo que hay que tratarlo siempre con especial cuidado. IE 10 requiere un trabajo adicional, ya que se basa en un borrador antiguo de la especificación que tiene una sintaxis diferente, y requiere el prefijo de proveedor -ms.

9 & 10. Alinear en el grid-container o en el grid-item

CSS Grid incluye prácticamente las mismas opciones de alineación que flexbox, por lo que podemos utilizarlo en el grid-container:

.container{ display: grid; align-items: center; justify-content: center;}

Ver el Pen
Centering 9: align on grid-container por Facundo Corradini (@facundocorradini)
en CodePen.

O sólo en un grid-item específico:

.container{ display: grid;}.element{ justify-self: center; align-self: center}

La falta de soporte del navegador heredado es la única limitación para esta técnica.

Ver el Pen
Centering 10: align on grid-item por Facundo Corradini (@facundocorradini)
en CodePen.

Pseudoelementos en una rejilla

De forma similar a la alternativa de flexbox, podríamos utilizar una rejilla de tres filas con pseudoelementos:

.container{ display: grid; grid-template-columns: 1fr; grid-template-rows: repeat(3, 1fr);}.container::before,.container::after{ content:"";}

Recuerda que 1fr en realidad significa minmax(auto, 1fr), por lo que las filas vacías no ocuparán necesariamente un tercio de la altura del contenedor. Se colapsarán según sea necesario hasta su valor mínimo de auto, y sin contenido, significa 0.

Ver el Pen
Centering 11 : grid + pseudos por Facundo Corradini (@facundocorradini)
en CodePen.

Esto puede parecer una tontería, pero nos permite realizar fácilmente uno de mis trucos favoritos de CSS Grid: combinar filas fr con minmax, lo que hará que se colapsen primero las fr vacías y luego las mixmax. Jenn Simmons tiene grandes ejemplos sobre esto.

Así que, teniendo los pseudos tomar las filas totalmente colapsables permitirá que el algoritmo de auto-colocación haga su magia en nuestros elementos reales. Excepto si necesitamos soportar IE, que carece de auto-colocación. Lo que nos lleva al siguiente método…

Colocación explícita en la fila de la rejilla

La rejilla de CSS permite que los elementos se coloquen explícitamente en una fila específica, por lo que la misma declaración de la rejilla anterior y el elemento colocado en la segunda fila será suficiente:

.container{ display:grid; grid-template-columns:1fr; grid-template-rows: repeat(3, 1fr);}.element{ grid-row: 2 / span 1; /* or grid-row: 2/3 */}

Este puede funcionar hasta IE10. Aunque no lo creas, IE fue uno de los primeros y más firmes defensores de la rejilla CSS, lanzándola ya en 2011 con IE10. Se basa en un borrador muy temprano que tiene una sintaxis completamente diferente, pero podemos hacer que funcione:

.container{ display: -ms-grid; -ms-grid-rows: (1fr); -ms-grid-columns: 1fr;}.element{ -ms-grid-column: 1; -ms-grid-row: 2;}

Ver el Pen
Centering 12 : colocación explícita en una cuadrícula por Facundo Corradini (@facundocorradini)
en CodePen.

Margin auto en un grid-item

De forma similar a flexbox, aplicar margin-auto en un grid-item lo centra en ambos ejes.

.container{ display: grid;}.element{ margin: auto;}

Vea el Pen
Centering 12 : colocación explícita en una rejilla por Facundo Corradini (@facundocorradini)
en CodePen.

Algunas (probables) implementaciones futuras

Según la especificación del CSS Box Alignment Module de nivel 3, align-content debería funcionar en el eje de bloques de los contenedores de bloques y contenedores multicol, por lo que (si los navegadores lo implementan) deberíamos poder centrar el contenido de esos contenedores igual que hacemos en los contenedores flex o grid.

Prueba LogRocket para estar 100% seguro de que tus elementos están bien centrados

«Se ve bien en mi máquina» no es suficiente. Con LogRocket, puedes ver el DOM (junto con esos molestos elementos centrados verticalmente) exactamente como lo hace el usuario final. Si estás interesado en monitorear y rastrear el uso de la CPU del lado del cliente, el uso de la memoria y más para todos tus usuarios en producción, prueba LogRocket.LogRocket Dashboard Free Trial Bannerhttps://logrocket.com/signup/

LogRocket es como un DVR para aplicaciones web, que graba todo lo que ocurre en tu aplicación o sitio web. En lugar de adivinar por qué ocurren los problemas, puede agregar e informar sobre las métricas clave de rendimiento del frontend, reproducir las sesiones de los usuarios junto con el estado de la aplicación, registrar las solicitudes de red y sacar a la luz automáticamente todos los errores.

Modernice la forma de depurar las aplicaciones web – Empiece a monitorizar de forma gratuita.

Conclusión

Deja una respuesta

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