Как выровнять текст по вертикали во flexbox?

Я хотел бы использовать flex box для вертикального выравнивания некоторого содержимого внутри <li> но не имея большого успеха.

Я проверил в Интернете, и многие учебники на самом деле используют div обертки, который получает align-items:center из настроек флекса на родителе, но мне интересно, можно ли вырезать этот дополнительный элемент?

Я решил использовать flex box в этом случае, так как высота элемента списка будет динамическим%.

* {
  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>

14 ответов

Решение

Редактировать: Пожалуйста, используйте ответ Michael_B вместо моего. Я бы удалил этот ответ, если бы мог, но принятые ответы не могут быть удалены.


Если вы сделаете flex-direction вертикальный (используя column) затем justify-content: center центры по вертикали. Тогда вы можете просто использовать text-align: center центрировать по горизонтали, а также.

li {
  display: flex;
  justify-content: center;
  flex-direction: column;
  text-align: center;
}

Вот оно в действии: http://codepen.io/anon/pen/Fkhgo

Вместо того, чтобы использовать align-self: center использование align-items: center,

Там нет необходимости менять flex-direction или использовать text-align (как предложено в другом ответе).

Вот ваш код, с одной настройкой, чтобы все это работало:

ul {
  height: 100%;
}

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

align-self свойство относится к гибким элементам. Кроме вашего li не гибкий элемент, потому что его родитель - ul - не имеет display: flex или же display: inline-flex применяется.

Следовательно ul не гибкий контейнер, li не гибкий элемент, и align-self не имеет никакого эффекта

align-items собственность похожа на align-self За исключением случаев, когда это касается гибких контейнеров.

Так как li гибкий контейнер, align-items может использоваться для вертикального центрирования дочерних элементов.

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

демонстрационный код


Технически, вот как align-items а также align-self Работа...

align-items свойство (на контейнере) устанавливает значение по умолчанию align-self (по предметам). Следовательно, align-items: center означает, что все элементы Flex будут установлены на align-self: center,

Но вы можете изменить это значение по умолчанию, настроив align-self на отдельные предметы.

Например, вы можете захотеть столбцы одинаковой высоты, поэтому контейнер установлен на align-items: stretch, Тем не менее, один элемент должен быть прикреплен к вершине, поэтому он установлен на align-self: flex-start,

пример


Как текст является гибким элементом?

Некоторые люди могут задаваться вопросом, как бег текста...

<li>This is the text</li>

является дочерним элементом li,

Причина в том, что текст, который явно не заключен в элемент встроенного уровня, алгоритмически оборачивается встроенным блоком. Это делает его анонимным встроенным элементом и потомком родителя.

Из спецификации CSS:

9.2.2.1 Анонимные встроенные блоки

Любой текст, который непосредственно содержится внутри элемента контейнера блока, должен рассматриваться как анонимный встроенный элемент.

Спецификация flexbox предусматривает аналогичное поведение.

4. Гибкие элементы

Каждый дочерний поток в гибком контейнере становится гибким элементом, а каждый непрерывный фрагмент текста, который непосредственно содержится в гибком контейнере, оборачивается в анонимный гибкий элемент.

Следовательно, текст в li это гибкий элемент

Лучший шаг - это просто вставить flexbox внутрь flexbox. Все, что вам нужно сделать, это дать ребенку align-items: center, Это будет вертикально выравнивать текст внутри его родителя.

// 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;
}

Для будущих гуглеров,

Ответ, получивший наибольшее количество голосов, и второй по значимости, также предназначен для решения этой конкретной проблемы, опубликованной OP, где контент (текст) был "алгоритмически союзником", заключенным во встроенный блочный элемент. НО, ваш случай может касаться центрирования нормального элемента вертикально внутри контейнера, что также применимо в моем случае, так что для этого все, что вам нужно, это

align-self: center;

Просто выкладываю это здесь, так как это лучший результат для вышеупомянутого запроса, а также я был довольно смущен в течение некоторого времени * Derp *

Я не буду писать ответ, потому что многие уже дали правильный. Однако я хочу показать вам полезный инструмент, который может избавить вас от подобных проблем в будущем.

В инструментах разработчика вашего браузера вам нужно проверить элемент и, нажав на значок, показанный на снимке экрана, нажать на значок.

Затем вам будет предложена возможность выбрать некоторые свойства для display: flex так что вы можете легко проверить все варианты быстро, не зная, что вы можете использовать

РЕЗУЛЬТАТ

HTML

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

Использовать align-items вместо того align-self и я также добавил flex-direction к 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%; 
}

Установите дисплей в li как гибкий и набор align-items к center.

li {
  display: flex;

  /* Align items vertically */
  align-items: center;

  /* Align items horizontally */
  justify-content: center;

}

Я лично также нацелен на псевдоэлементы и использовал border-box( Универсальный селектор * и псевдоэлементы)

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

С помощью display: flex вы можете контролировать вертикальное выравнивание 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>

Align-selfне выравнивает элементы внутри li. Вместо этого он выравнивает ли в целом.

С использованием align-itemsизменит текст внутри li. Посмотрите этот код. Оно работает.

* {
  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>

Это зависит от вашей высоты li, просто назовите еще одну высоту строки

* {
  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:50px;line-height:50px;
}
<ul>
  <li>This is the text</li>
</ul>

* {
  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>

Вы могли бы изменить ul а также li отображает в table а также table-cell, Затем, vertical-align будет работать для вас:

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

Другие вопросы по тегам