Centrado en CSS: una guía completa

Centrar las cosas en CSS es el ejemplo secundario de las quejas de CSS. ¿Por qué tiene que ser tan difícil? Se burlan. Creo que el problema no es que sea difícil de hacer, sino que hay tantas formas diferentes de hacerlo, dependiendo de la situación, es difícil saber a cuál recurrir.

Así que vamos a convertirlo en un árbol de decisiones y, con suerte, hacerlo más fácil.

Necesito centrarme …

Horizontalmente

¿Son elementos en línea o en línea * (como texto o enlaces)?

Puede centrar elementos en línea horizontalmente, dentro de un elemento padre a nivel de bloque, con solo:

.center-children {
  text-align: center;
}

See the Pen Centering Inline Elements by Chris Coyier (@chriscoyier) on CodePen.

Esto funcionará para inline, inline-block, inline-table, inline-flex, etc.

¿Es un elemento de nivel de bloque?

Puede centrar un elemento a nivel de bloque dándole margin-left y margin-right de auto (y tiene un ancho establecido; de lo contrario, sería de ancho completo y no necesitaría centrarse). Eso a menudo se hace con taquigrafía como esta:

.center-me {
  margin: 0 auto;
}

See the Pen Centering Single Block Level Element by Chris Coyier (@chriscoyier) on CodePen.

Esto funcionará sin importar el ancho del elemento de nivel de bloque que está centrando o el elemento principal.

Tenga en cuenta que no puede hacer flotar un elemento hacia el centro.

¿Hay más de un elemento a nivel de bloque?

Si tiene dos o más elementos a nivel de bloque que deben centrarse horizontalmente en una fila, es probable que se le sirva mejor si los convierte en un tipo de visualización diferente. A continuación, se muestra un ejemplo de cómo convertirlos en inline-block y un ejemplo de flexbox:

See the Pen Centering Row of Blocks by Chris Coyier (@chriscoyier) on CodePen.

A menos que quiera decir que tiene varios elementos de nivel de bloque apilados uno encima del otro, en cuyo caso la técnica de margen automático sigue estando bien:

See the Pen Centering Blocks on Top of Each Other by Chris Coyier (@chriscoyier) on CodePen.

Verticalmente

El centrado vertical es un poco más complicado en CSS.

¿Son elementos en línea o en línea * (como texto o enlaces)?

¿Es una sola línea?

A veces, los elementos en línea / de texto pueden aparecer centrados verticalmente, solo porque hay un relleno igual por encima y por debajo de ellos.

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

See the Pen Centering text (kinda) with Padding by Chris Coyier (@chriscoyier) on CodePen.

Si el relleno no es una opción por alguna razón, y está tratando de centrar un texto que sabe que no se ajustará, hay un truco en el que hacer que la altura de la línea sea igual a la altura centrará el texto.

.center-text-trick {
  height: 100px;
  line-height: 100px;
  white-space: nowrap;
}

See the Pen Centering a line with line-height by Chris Coyier (@chriscoyier) on CodePen.

¿Son varias líneas?

El relleno igual en la parte superior e inferior también puede dar el efecto centrado para varias líneas de texto, pero si eso no va a funcionar, tal vez el elemento en el que se encuentra el texto puede ser una celda de tabla, ya sea literalmente o para comportarse como una con CSS. La propiedad vertical-align maneja esto, en este caso, a diferencia de lo que normalmente hace, que es manejar la alineación de elementos alineados en una fila.

See the Pen Centering text (kinda) with Padding by Chris Coyier (@chriscoyier) on CodePen.

Si algo similar a una tabla está fuera, ¿quizás podría usar flexbox? Se puede hacer que un solo niño flexible se centre en un padre flexible con bastante facilidad.

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

See the Pen Vertical Center Multi Lines of Text with Flexbox by Chris Coyier (@chriscoyier) on CodePen.

Recuerde que solo es realmente relevante si el contenedor principal tiene una altura fija (px,%, etc.), por lo que el contenedor aquí tiene una altura.

Si ambas técnicas no funcionan, puede emplear la técnica del «elemento fantasma», en la que se coloca un pseudoelemento de altura completa dentro del contenedor y el texto se alinea verticalmente con él.

.ghost-center {
  position: relative;
}
.ghost-center::before {
  content: " ";
  display: inline-block;
  height: 100%;
  width: 1%;
  vertical-align: middle;
}
.ghost-center p {
  display: inline-block;
  vertical-align: middle;
}

See the Pen Ghost Centering Multi Line Text by Chris Coyier (@chriscoyier) on CodePen.

¿Es un elemento a nivel de bloque?

¿Conoce la altura del elemento?

Es bastante común no conocer la altura en el diseño de la página web, por muchas razones: si cambia el ancho, el reflujo del texto puede cambiar la altura. La variación en el estilo del texto puede cambiar la altura. La variación en la cantidad de texto puede cambiar la altura. Los elementos con una relación de aspecto fija, como las imágenes, pueden cambiar de altura cuando se redimensionan. Etc.

Pero si conoce la altura, puede centrar verticalmente como:

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

See the Pen Center Block with Fixed Height by Chris Coyier (@chriscoyier) on CodePen.

¿Es el elemento de altura desconocida?

Todavía es posible centrarlo empujándolo hacia la mitad de su altura después de empujarlo hacia abajo hasta la mitad:

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

See the Pen Center Block with Unknown Height by Chris Coyier (@chriscoyier) on CodePen.

¿Te importa si el elemento estira la altura del contenedor?

Si no es así, solo necesita el contenido dentro centrado verticalmente, el uso de tablas o visualización CSS para convertir elementos en tablas puede hacer el truco.

See the Pen Center Block with Table Stretch by Chris Coyier (@chriscoyier) on CodePen.

¿Puedes usar flexbox?

No es una gran sorpresa, esto es mucho más fácil en flexbox.

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

See the Pen Center Block with Unknown Height with Flexbox by Chris Coyier (@chriscoyier) on CodePen.

También puede centrarse en flexbox usando margin: auto; en el elemento hijo.

Tanto horizontal como verticalmente

Puede combinar las técnicas anteriores de cualquier manera para obtener elementos perfectamente centrados. Pero encuentro que esto generalmente se divide en tres campos:

¿El elemento es de ancho y alto fijos?

El uso de márgenes negativos iguales a la mitad de ese ancho y alto, después de haberlo colocado absolutamente al 50% / 50%, lo centrará con una excelente compatibilidad con todos los navegadores:

.parent {
  position: relative;
}

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

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

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

See the Pen Center Block with Fixed Height and Width by Chris Coyier (@chriscoyier) on CodePen.

¿Es el elemento de ancho y alto desconocidos?

Si no conoce el ancho o el alto, puede usar la propiedad de transformación y una traducción negativa del 50% en ambas direcciones (se basa en el ancho / alto actual del elemento) para centrar:

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

See the Pen Center Block with Unknown Height and Width by Chris Coyier (@chriscoyier) on CodePen.

¿Puedes usar flexbox?

Para centrar en ambas direcciones con flexbox, debe utilizar dos propiedades de centrado:

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

See the Pen Center Block with Unknown Height and Width with Flexbox by Chris Coyier (@chriscoyier) on CodePen.

¿Puedes usar la cuadrícula?

Este es solo un pequeño truco (enviado por Lance Janssen) que funcionará prácticamente para un elemento:

body, html {
  height: 100%;
  display: grid;
}
span { /* thing to center */
  margin: auto;
}

See the Pen Centering with Grid by Chris Coyier (@chriscoyier) on CodePen.

Conclusión

Puedes centrar totalmente las cosas en CSS.