Последняя маржа/отступы, сжимающиеся в flexbox/сетке

У меня есть список элементов, которые я пытаюсь выполнить в прокручиваемом горизонтальном макете с flexbox.

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

Есть ли способ остановить это или хорошее обходное решение?

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
  display: flex;
  height: 300px;
  overflow: auto;
  width: 600px;
  background: orange;
}
ul li {
  background: blue;
  color: #fff;
  padding: 90px;
  margin: 0 30px;
  white-space: nowrap;
  flex-basis: auto;
}
<div class="container">
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
  </ul>
</div>

Ответ 1

Проблема

По-видимому, это поведение по умолчанию для всех основных браузеров: при тестировании правый край рушится в Firefox, Chrome, Safari, IE11 и Edge.

Не вдаваясь в много экспериментов, я предлагаю, чтобы это поведение было определено в спецификации:

10.3.3 Блочные, не замененные элементы в нормальном режиме Поток

В числе используемых значений другого Свойства:

margin-left + border-left-width + padding-left + width + padding-right + border-right-width + margin-right= ширина содержащий блок

Если width не auto и border-left-width + padding-left + width + padding-right + border-right-width (плюс любой из margin-left или margin-right, которые не являются auto), больше ширину содержащего блока, то любые значения auto для margin-left или margin-right для следующих правил как ноль.

Если все вышеперечисленное имеет вычисленное значение, отличное от auto, значения называются "чрезмерными" и одно из используемых значений будет отличаться от его вычисленного значения. Если directionсвойство содержащего блока имеет значение ltr, указанное значение margin-right игнорируется, и значение вычисляется так, как чтобы сделать равенство истинным. Если значение direction равно rtl, это происходит вместо margin-left

(выделено курсивом)

Итак, в соответствии с моделью визуального форматирования CSS ваш содержащий блок может быть "чрезмерно ограниченным" и, как результат, правом маржа отбрасывается.


Решение

Одним из решений является добавление правой границы к вашему последнему элементу:

li:last-child {
  border-right: 30px solid orange;
}

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
  display: flex;
  height: 300px;
  overflow: auto;
  width: 600px;
  background: orange;
}
ul li {
  background: blue;
  color: #fff;
  padding: 90px;
  margin: 0 30px;
  white-space: nowrap;
  flex-basis: auto;
}
li:last-child {
  border-right: 30px solid orange;
}
<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
</ul>

Ответ 2

Ваша проблема - не само по себе. Это полоса прокрутки, определяющая только видимое содержимое элемента.

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

Это решение обрабатывает это, используя псевдо на последнем дочернем

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
  display: flex;
  height: 300px;
  overflow: auto;
  width: 600px;
  background: orange;
}
ul li {
  background: blue;
  color: #fff;
  padding: 90px;
  margin: 0 30px;
  white-space: nowrap;
  flex-basis: auto;
  position: relative;
}
li:last-child:after {
  content: "";
  width: 30px;
  height: 1px;
  position: absolute;
  left: 100%;
  top: 0px;
}
<div class"container">
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
  </ul>
</div>

Ответ 3

Вы можете установить width и overflow в контейнере div и установить display: inline-flex, а не flex на ul, чтобы размер гибкой рамки был рассчитан на основе элементы внутри, и все дополнения и маржа будут применяться без каких-либо проблем.

.container {
  width: 600px;
  overflow: auto;
}

.container ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: inline-flex;
  background: orange;
}

.container li {
  padding: 60px;
  margin: 0 30px;
  white-space: nowrap;
  background: blue;
  color: #fff;
}
<div class="container">
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
  </ul>
</div>

Ответ 4

См. решение. Я удаляю white-space, flex-basis и margin, чтобы предоставить вам чистое решение flexbox.

Он ретранслирует на flex-flow: row (горизонтальный), justify-content: space-around (ваш запас) и не более!! width изменен на 1200px, так как заполнение 90px устанавливает общую ширину ячеек больше 600px (определенный в вашем фрагменте).

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-flow: row ;
  justify-content: space-around;
  height: 300px;
  overflow: auto;
  width: 1200px;
  background: orange;
}
ul li {
  background: blue;
  color: #fff;
  padding: 90px;
}
<div class"container">
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
  </ul>
</div>