¿Cómo alinear verticalmente el texto dentro de un flexbox?

425

Me gustaría usar flexbox para alinear verticalmente parte del contenido dentro de, <li>pero no tener gran éxito.

Lo revisé en línea y muchos de los tutoriales en realidad usan un envoltorio div que obtiene la align-items:centerconfiguración de flex en el padre, pero me pregunto si es posible cortar este elemento adicional.

He optado por usar flexbox en este caso, ya que la altura del elemento de la lista será dinámica %.

* {
  padding: 0;
  margin: 0;
}

html,
body {
  height: 100%;
}

ul {
  height: 100%;
}

li {
  display: flex;
  justify-content: center;
  align-self: center;
  background: silver;
  width: 100%;
  height: 20%;
}
<ul>
  <li>This is the text</li>
</ul>

styler
fuente

Respuestas:

545

En lugar de usar el align-self: centeruso align-items: center.

No hay necesidad de cambiar flex-directiono usar text-align.

Aquí está su código, con un ajuste, para que todo funcione:

ul {
  height: 100%;
}

li {
  display: flex;
  justify-content: center;
  /* align-self: center;    <---- REMOVE */
  align-items: center;   /* <---- NEW    */
  background: silver;
  width: 100%;
  height: 20%; 
}

La align-selfpropiedad se aplica a artículos flexibles . Excepto que su lino es un elemento flexible porque su padre - el ul- no tiene display: flexni display: inline-flexaplicado.

Por lo tanto, ulno es un contenedor flexible, lino es un elemento flexible y align-selfno tiene ningún efecto.

La align-itemspropiedad es similar a align-self, excepto que se aplica a contenedores flexibles .

Dado que lies un contenedor flexible, align-itemsse puede utilizar para centrar verticalmente los elementos secundarios.

demostración de codepen


Técnicamente, así es como align-itemsy cómo align-selffunciona ...

La align-itemspropiedad (en el contenedor) establece el valor predeterminado de align-self(en los elementos). Por lo tanto, align-items: centersignifica que todos los elementos flexibles se establecerán en align-self: center.

Pero puede anular este valor predeterminado ajustando los align-selfelementos individuales.

Por ejemplo, es posible que desee columnas de igual altura, por lo que el contenedor se establece en align-items: stretch. Sin embargo, un elemento debe estar fijado en la parte superior, por lo que está configurado en align-self: flex-start.

ejemplo


¿Cómo es el texto un elemento flexible?

Algunas personas pueden preguntarse cómo una serie de textos ...

<li>This is the text</li>

es un elemento hijo de li.

La razón es que el texto que no está envuelto explícitamente por un elemento de nivel en línea está envuelto algorítmicamente por un cuadro en línea. Esto lo convierte en un elemento en línea anónimo y secundario del padre.

De la especificación CSS:

9.2.2.1 Cuadros anónimos en línea

Cualquier texto que esté contenido directamente dentro de un elemento contenedor de bloques debe tratarse como un elemento anónimo en línea.

La especificación flexbox proporciona un comportamiento similar.

4. Artículos flexibles

Cada elemento secundario en flujo de un contenedor flexible se convierte en un elemento flexible, y cada corrida contigua de texto que está contenida directamente dentro de un contenedor flexible se envuelve en un elemento flexible anónimo.

Por lo tanto, el texto en el lies un elemento flexible.

Michael Benjamin
fuente
2
Me gusta align-items: baseline. Bueno para diferentes alturas provenientes de diferentes caracteres Unicode, etc.
qräbnö
1
Gracias por explicar y vincular el concepto de cuadros en línea anónimos ... realmente ayuda a aclarar por qué algunos efectos que puede lograr mediante prueba y error funcionan de la manera en que lo hacen.
squarecandy
39

La respuesta más votada es para resolver este problema específico publicado por OP, donde el contenido (texto) estaba envuelto dentro de un inline-blockelemento. Algunos casos pueden ser sobre centrar un elemento normal verticalmente dentro de un contenedor , que también se aplica en mi caso, por lo que para eso todo lo que necesita es:

align-self: center;
Mohd Abdul Mujib
fuente
25

El mejor movimiento es simplemente anidar una caja flexible dentro de una caja flexible . Todo lo que tienes que hacer es darle al niño align-items: center. Esto alineará verticalmente el texto dentro de su padre.

// Assuming a horizontally centered row of items for the parent but it doesn't have to be
.parent {
  align-items: center;
  display: flex;
  justify-content: center;
}

.child {
  display: flex;
  align-items: center;
}
serraosayos
fuente
Si quieres un texto centrado perfecto. text-align:centerno funciona solo Úselo align-items: centercon él.
Tzwenni
8

RESULTADO

ingrese la descripción de la imagen aquí

HTML

<ul class="list">
  <li>This is the text</li>
  <li>This is another text</li>
  <li>This is another another text</li>
</ul>

Use en align-itemslugar de align-selfy también agregué flex-directiona column.

CSS

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

.list {
  display: flex;
  justify-content: center;
  flex-direction: column;  /* <--- I added this */
  align-items: center;   /* <--- Change here */
  height: 100px;
  width: 100%;
  background: silver;
}

.list li {  
  background: gold;
  height: 20%; 
}
Wilson
fuente
1

* {
  padding: 0;
  margin: 0;
}

html,
body {
  height: 100%;
}

ul {
  height: 100%;
}

li {
 display: flex;
 justify-content: center;
 align-items: center;
 background: silver;
 width: 100%;
 height: 20%;
}
<ul>
  <li>This is the text</li>
</ul>

Anatoly Gorchuk
fuente
0

* {
  padding: 0;
  margin: 0;
}
html, body {
  height: 100%;
}
ul {
  height: 100%;
}
li {
  display: flex;
  justify-content: center;
  align-items:center;
  background: silver;
  width: 100%;
  height: 20%;
}
<ul>
  <li>This is the text</li>
</ul>

Swapnil
fuente
Las respuestas de solo código no son muy útiles ... agregue comentarios o una explicación de lo que hizo y por qué funciona.
random_user_name
0

Utilizando display: flexpuede controlar la alineación vertical de elementos HTML.

.box {
  height: 100px;
  display: flex;
  align-items: center; /* Vertical */
  justify-content: center; /* Horizontal */
  border:2px solid black;
}

.box div {
  width: 100px;
  height: 20px;
  border:1px solid;
}
<div class="box">
  <div>Hello</div>
  <p>World</p>
</div>

Ankur prajapati
fuente
-6

Se podría cambiar el uly lipantallas para tabley table-cell. Entonces, vertical-alignfuncionaría para ti:

ul {
    height: 20%;
    width: 100%;
    display: table;
}

li {
    display: table-cell;
    text-align: center;
    vertical-align: middle;
    background: silver;
    width: 100%; 
}

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

LcSalazar
fuente
Funciona bien hasta que agregue otro elemento de la lista allí.
George
1
Es cierto ... Pero eso nunca fue mencionado
LcSalazar
has cambiado la altura para estar en el ul en lugar del li? cada altura de li será dinámica, así que esto no es algo que pueda usar, tengo miedo
styler
@LcSalazar Por lo general, no usaría una lista si solo tuviera la intención de tener un elemento. Para eso están los divs.
Ben Visness
2
Cierto otra vez ... Pero no digo que este sea el escenario perfecto. Acabo de publicar una solución que responde la pregunta tal como es. Espero que esta información sea útil para otra persona que la lea y tenga otro escenario ...
LcSalazar