Когда есть только одна строка «гибких элементов», Chrome и Firefox показывают разные результаты. Когда имеется более одной строки (перенос), Chrome и Firefox показывают одинаковый результат!

Так почему это происходит? Это ошибка, или есть какое-то «значение по умолчанию» или разница, которую мне не хватает?

body{
    background-color: teal;
}

.flexContainer{
    background-color: blue;
    border: 1px solid black;
    height: 300px;
}
.flexItem{
    background-color: red;
    border: 1px solid black;
}

.flexContainer{
    display: flex;
    flex-flow: row wrap;
    justify-content: center;
    align-items: stretch;
    align-content: flex-start;
}

.flexItem{ 
    flex: 0 1 0; 
}
<div class="flexContainer">
    <div class="flexItem">1111111111111111111</div>
    <div class="flexItem">2222<br/>2222</div>
    <div class="flexItem">3333<br/>3333<br/>3333</div>
    <div class="flexItem">4444444444444444444</div>
</div>
3
J.L. Yokata 11 Сен 2018 в 22:39

1 ответ

Лучший ответ

Источник проблемы

Вот источник проблемы:

.flexContainer {
    display: flex;
    flex-flow: row wrap;
    justify-content: center;
    align-items: stretch;
    align-content: flex-start; <-- problem
}

Задний план

Свойство align-content управляет перекрестным выравнивание осей гибких линий внутри гибкого контейнера. Думайте о гибких линиях как о строках или столбцах (в зависимости от {{X1 }}), в которых живут гибкие элементы. Другими словами, align-content распределяет пространство между гибкими линиями и вокруг них, упаковывая их сверху, снизу, по центру и т. Д. (См. полный список значений ).

Поскольку align-content распределяет пространство между и вокруг гибких линий, он может работать только с многострочными гибкими контейнерами. (Одна линия проходит по всей длине поперечной оси контейнера, не оставляя свободного места для работы align-content.)

Очевидно, что многострочный контейнер - это контейнер с более чем одной строкой (гибкие элементы обернуты). Однако технически многострочный контейнер - это просто контейнер с { {X0}} или flex-wrap: wrap-reverse (независимо от того, были ли элементы гибкости упакованы или даже существуют).

Та же концепция применяется к однострочному гибкому контейнеру, который является контейнером с flex-wrap: nowrap. Как обсуждалось выше, свойство align-content не действует в контейнерах nowrap.

§ 8.4. Упаковочные гибкие линии: align-content собственность

Свойство align-content выравнивает линии гибкого контейнера внутри гибкий контейнер, когда на поперечной оси есть лишнее пространство, аналогично тому, как justify-content выравнивает отдельные элементы внутри главная ось. Обратите внимание, что это свойство не влияет на однострочную гибкость контейнер .

§ 6. Гибкость Линии

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

  • однострочный гибкий контейнер (т.е. контейнер с flex-wrap: nowrap) размещает всех своих дочерних элементов в одной строке, даже если это вызвать переполнение его содержимого.

  • Многострочный гибкий контейнер (т.е. контейнер с flex-wrap: wrap или flex-wrap: wrap-reverse) разбивает свои гибкие элементы на несколько строк, подобно тому, как текст разбивается на новую строку. когда он становится слишком широким, чтобы поместиться на существующей линии.


Несоответствие между Chrome и Firefox / Edge

Снова посмотрим на ваш код:

body {
  background-color: teal;
}

.flexContainer {
  background-color: blue;
  border: 1px solid black;
  height: 300px;
}

.flexItem {
  background-color: red;
  border: 1px solid black;
}

.flexContainer {
  display: flex;
  flex-flow: row wrap;
  justify-content: center;
  align-items: stretch;
  align-content: flex-start;
}

.flexItem {
  flex: 0 1 0;
}
<div class="flexContainer">
  <div class="flexItem">1111111111111111111</div>
  <div class="flexItem">2222<br/>2222</div>
  <div class="flexItem">3333<br/>3333<br/>3333</div>
  <div class="flexItem">4444444444444444444</div>
</div>

Обратите внимание на три вещи:

(1) Фактической упаковки нет. Все четыре элемента находятся в одной строке. Гибкий контейнер состоит из одной строки.

(2) Свойство flex-wrap установлено на wrap (в сокращении flex-flow).

(3) Свойство align-content установлено на flex-start.

Давайте разберемся с этим.

Поскольку в гибком контейнере всего одна строка, Chrome игнорирует align-content. Как написано в спецификации (см. Выше):

Свойство align-content не влияет на однострочный гибкий контейнер .

Итак, это интерпретация Chrome. Если действительно одна строка, игнорируйте align-content.

Переключайтесь между wrap и nowrap в Chrome. Нет никакой разницы.

С другой стороны, поскольку для контейнера установлено значение flex-wrap: wrap, это технически создает многострочный гибкий контейнер, что касается Firefox и Edge. Фактическая упаковка или наличие гибких элементов не имеет значения.

Как написано в спецификации (см. Выше):

Многострочный гибкий контейнер (т.е. контейнер с flex-wrap: wrap или flex-wrap: wrap-reverse) разбивает свои гибкие элементы на несколько строк ...

Переключайтесь между wrap и nowrap в Firefox и Edge. Есть разница.

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


Соответствие стандартам

Что касается соблюдения спецификации, я бы сказал, что Firefox и Edge полностью соответствуют требованиям. Кажется, что они наиболее точно соответствуют формулировке спецификации.

Однако я бы не стал характеризовать поведение Chrome как «ошибку». То, что они сделали, скорее всего, было вмешательством .

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

Вмешательство кажется стандартной практикой в ​​Chrome. Примеры:


Дополнительная информация

10
Michael Benjamin 25 Сен 2018 в 00:26