Flexbox align-items: baseline работает, но align-self: baseline не работает. Почему?

кажется, я наблюдаю какое-то запутанное поведение с flexbox, особенно при попытке использовать align-self: baseline. Основная проблема заключается в том, что он просто не работает; следующий фрагмент демонстрирует проблему:

.flex-form {
  display: flex;
}

.flex-form label {
  align-self: baseline;
}

input[type=text] {
  border: 1px solid black;
  font-size: 16px;
  margin: 0 10px;
  padding: 5px;
}

button {
  background-color: white;
  border: 1px solid black;
  margin: 0;
}
<form class="flex-form">
  <label>Label: </label>
  <input type="text" placeholder=" " />
  <button type="submit">Submit</button>
</form>

вот скриншот того, как выглядит вывод:

как вы можете видеть, базисный метки не согласован с другими элементы формы, несмотря на наличие align-self: baseline set. Если я использую align-items: baseline на родительском контейнере, однако, я получаю другой результат:

.flex-form {
  display: flex;
  align-items: baseline;
}

input[type=text] {
  border: 1px solid black;
  font-size: 16px;
  margin: 0 10px;
  padding: 5px;
}

button {
  align-self: stretch;
  background-color: white;
  border: 1px solid black;
  margin: 0;
}
<form class="flex-form">
  <label>Label: </label>
  <input type="text" placeholder=" " />
  <button type="submit">Submit</button>
</form>

это правильное поведение в соответствии со спецификацией, или это ошибка? Если так, то почему? Есть ли обходной путь? Для справки, я тестировал Chrome 54, Safari 9.1.2 и Firefox 50 на macOS 10.11.6, и все они, похоже, показывают те же результаты.

1 ответов


решение

если вы хотите базовой линии для всех элементов, применяются align-self: baseline каждому или, проще говоря, set align-items: baseline на контейнере.

объяснение

начальная настройка контейнера flex является align-items: stretch.

это значит что все детали гибкого трубопровода расширят полную длину поперечной оси контейнера.

вот что происходит в вашем макете. за исключением, вы переопределили align-items: stretch on один гибкий элемент (label), путем применения align-self: baseline.

пока другие детали гибкого трубопровода протягивают, ярлык имеет baseline инструкция – но нет точки отсчета.

спецификации:

8.3. Выравнивание поперечной оси:align-items и align-self свойства

baseline

если встроенная ось элемента flex совпадает с поперечной осью, это значение идентично flex-start.

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

Хорошо, давайте разберем это:

  • первая строка не относится. В этом случае flex пункт встроенные оси это то же самое, что и основная ось (горизонтальная), а не поперечная ось (вертикальная), поэтому baseline не разрешено flex-start.

  • "...все участвующие элементы flex на линии выровнены таким образом, чтобы их базовые линии выровнялись..." Ну, есть только один элемент с базовой линии. Нет никаких других исходных данных. По-видимому, браузер возвращается к flex-start в такой ситуации (но я не видел официального ссылка на это поведение).

остальная часть языка спецификаций не имеет отношения к этому вопросу, но подробно рассматривается в этом соответствующем посте:в чем разница между flex-start и базовой линией?