Flexbox: centrado horizontal y vertical

Cómo centrar div horizontalmente, y verticalmente dentro del contenedor usando flexbox. En el siguiente ejemplo, quiero que cada número debajo de la otra (en filas), que se centran horizontalmente.

Comienza el snippet: js hide: false console: true babel: false -->

.flex-container {
  padding: 0;
  margin: 0;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: center;
}
row {
  width: 100%;
}
.flex-item {
  background: tomato;
  padding: 5px;
  width: 200px;
  height: 150px;
  margin: 10px;
  line-height: 150px;
  color: white;
  font-weight: bold;
  font-size: 3em;
  text-align: center;
}
<div class="flex-container">
  <div class="row">
    <span class="flex-item">1</span>
  </div>
  <div class="row">
    <span class="flex-item">2</span>
  </div>
  <div class="row">
    <span class="flex-item">3</span>
  </div>
  <div class="row">
    <span class="flex-item">4</span>
  </div>
</div>

Fin del fragmento;

http://codepen.io/anon/pen/zLxBo

Solución

Creo que quieres algo como lo siguiente.

begin snippet: js hide: false console: true babel: false -->

html, body {
    height: 100%;
}
body {
    margin: 0;
}
.flex-container {
    height: 100%;
    padding: 0;
    margin: 0;
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
    align-items: center;
    justify-content: center;
}
.row {
    width: auto;
    border: 1px solid blue;
}
.flex-item {
    background-color: tomato;
    padding: 5px;
    width: 20px;
    height: 20px;
    margin: 10px;
    line-height: 20px;
    color: white;
    font-weight: bold;
    font-size: 2em;
    text-align: center;
}
<div class="flex-container">
    <div class="row"> 
        <div class="flex-item">1</div>
        <div class="flex-item">2</div>
        <div class="flex-item">3</div>
        <div class="flex-item">4</div>
    </div>
</div>

Fin del fragmento;

Vea la demostración en: http://jsfiddle.net/audetwebdesign/tFscL/

Tus elementos .flex-item deben ser de nivel de bloque (div en lugar de span) si quieres que la altura y el relleno superior/inferior funcionen correctamente.

Además, en .row, establece el ancho en auto en lugar de 100%.

Tus propiedades .flex-container están bien.

Si quieres que el .row esté centrado verticalmente en el puerto de vista, asigna una altura del 100% a html y body, y también pon a cero los márgenes de body.

Ten en cuenta que .flex-container necesita una altura para ver el efecto de alineación vertical, de lo contrario, el contenedor calcula la altura mínima necesaria para encerrar el contenido, que es menor que la altura del puerto de vista en este ejemplo.

**Nota de pie de página Las propiedades flex-flow, flex-direction, flex-wrap podrían haber facilitado la implementación de este diseño. Creo que el contenedor .row no es necesario a menos que quieras añadir algún estilo alrededor de los elementos (imagen de fondo, bordes y demás).

Un recurso útil es: http://demo.agektmr.com/flexbox/

Comentarios (8)

Cómo centrar elementos vertical y horizontalmente en Flexbox

A continuación se presentan dos soluciones generales de centrado.

Una para elementos flex alineados verticalmente (flex-dirección: columna) y la otra para elementos flex alineados horizontalmente (flex-dirección: fila).

En ambos casos la altura de los divs centrados puede ser variable, indefinida, desconocida, lo que sea. La altura de los divs centrados no importa.

Aquí está el HTML para ambos:

<div id="container">

    <div class="box" id="bluebox">
        <p>DIV #1</p>
    </div>

    <div class="box" id="redbox">
        <p>DIV #2</p>
    </div>

</div>

CSS (excluyendo los estilos decorativos)

Cuando los elementos flexibles se apilan verticalmente:

#container {
    display: flex;           /* establish flex container */
    flex-direction: column;  /* make main axis vertical */
    justify-content: center; /* center items vertically, in this case */
    align-items: center;     /* center items horizontally, in this case */
    height: 300px;
}

.box {
    width: 300px;
    margin: 5px;
    text-align: center;     /* will center text in <p>, which is not a flex item */
}

[]

[DEMO](http://jsfiddle.net/8o29y7pd/)


Cuando los elementos flexibles se apilan horizontalmente:

Ajuste la regla flex-dirección del código anterior.

#container {
    display: flex;
    flex-direction: row;     /* make main axis horizontal (default setting) */
    justify-content: center; /* center items horizontally, in this case */
    align-items: center;     /* center items vertically, in this case */
    height: 300px;
}

[]

[DEMO](http://jsfiddle.net/8o29y7pd/3/)


Centrar el contenido de los elementos flexibles

El alcance de un contexto de formato flexible está limitado a una relación padre-hijo. Los descendientes de un contenedor flexible más allá de los hijos no participan en el diseño flexible e ignorarán las propiedades de flex. Esencialmente, las propiedades de flex no son heredables más allá de los hijos.

Por lo tanto, siempre tendrá que aplicar display: flex o display: inline-flex a un elemento padre para aplicar las propiedades de flex al hijo.

Para centrar vertical y/u horizontalmente el texto u otro contenido de un elemento flex, haga del elemento un contenedor flex (anidado) y repita las reglas de centrado.

.box {
    display: flex;
    justify-content: center;
    align-items: center;        /* for single line flex container */
    align-content: center;      /* for multi-line flex container */
}

Más detalles aquí: https://stackoverflow.com/q/25311541/3597276

Alternativamente, puedes aplicar margin: auto al elemento de contenido del elemento flex.

p { margin: auto; }

Aprenda sobre los márgenes auto de flex aquí: Métodos para alinear elementos de flex (ver cuadro#56).


Centrar múltiples líneas de elementos flex

Cuando un contenedor flex tiene múltiples líneas (debido a la envoltura) la propiedad align-content será necesaria para la alineación entre ejes.

De la especificación:

8.4. Empaquetado de líneas flexibles: la propiedad `align-content

propiedad**](https://www.w3.org/TR/css-flexbox-1/#align-content-property)

La propiedad align-content alinea las líneas de un contenedor flexible dentro del contenedor flex cuando hay espacio extra en el eje transversal, de forma similar a como justify-content alinea los elementos individuales dentro del eje principal. Nota: esta propiedad no tiene efecto en un contenedor flexible de una sola línea.

Más detalles aquí: https://stackoverflow.com/q/42613359/3597276


Soporte del navegador

Flexbox es compatible con los principales navegadores, excepto IE < 10. Algunas versiones recientes de navegadores, como Safari 8 e IE10, requieren prefijos del proveedor. Para una forma rápida de añadir prefijos utilice Autoprefixer. Más detalles en esta respuesta.


Solución de centrado para navegadores antiguos

Para una solución alternativa de centrado utilizando la tabla CSS y las propiedades de posicionamiento, consulte esta respuesta: https://stackoverflow.com/a/31977476/3597276

Comentarios (5)

No olvide utilizar los atributos específicos de los navegadores importantes:

align-items: center; -->

-webkit-box-align: center;
-moz-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;

justify-content: center; -->

-webkit-box-pack: center;
-moz-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;

Podrías leer estos dos enlaces para entender mejor a flex: http://css-tricks.com/almanac/properties/j/justify-content/ y http://ptb2.me/flexbox/

Buena suerte.

Comentarios (6)