Как реализовать смещение чётных строк меню при переносе

Хочу добиться реализации динамического меню (кол-во элементов и их содержимое неизвестно), при котором каждая нечётная строчка меню должна иметь отступ от конца строки, а каждая чётная - от начала. Должно получиться, примерно, как на скриншоте:

введите сюда описание изображения

Пробовал собрать подобное на flex-ах, но не знаю способа выбрать нужную строчку при переносе. Поскольку элементы переносятся в зависимости от размера, нельзя точно сказать, какой элемент списка будет находится в конце строки, а какой в начале (и, соответственно, нельзя выбрать по nth-child).

Реализация на flex-ax необязательна. Но, при этом, хотелось бы обойтись без использования JS.

И ещё несколько моментов:

  • В последней строчке, элементы должны быть рядом друг с другом (а не как сейчас они размещены, по правилу space-beetween).
  • элемент .more-menu должен всегда находится в конце строки, и смещаться согласно текущему номеру строки (на скриншоте, например, он находится на 5-ой строке и поэтому смещается от правого края).
  • Также, при переносе, элемент .more-menu не должен быть единственным элементом на строке (хотя, наверно конкретно это без JS не реализовать).
  • Меню должно следовать этому паттерну формирования в любом разрешении экрана.

Собственно, вопрос - как подобное можно реализовать средствами CSS ?

body {
  margin: 0;
  padding: 0;
}

ul {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  font-size: 20px;
}
ul li {
  margin-right: 28px;
}
ul li:nth-child(16n-8) {
  color: red;
  padding-right: 30px;
}
ul li:nth-child(16n-7) {
  color: brown;
  padding-left: 30px;
}
.more-menu {
  padding-right: 30px;
}
<ul>
  <li>item-1</li>
  <li>item-2</li>
  <li>item-3</li>
  <li>item-4</li>
  <li>item-5</li>
  <li>item-6</li>
  <li>item-7</li>
  <li>item-8</li>
  <li>item-9</li>
  <li>item-10</li>
  <li>item-11</li>
  <li>item-12</li>
  <li>item-13</li>
  <li>item-14</li>
  <li>item-15</li>
  <li>item-16</li>
  <li>item-17</li>
  <li>item-18</li>
  <li>item-19</li>
  <li>item-20</li>
  <li>item-21</li>
  <li>item-22</li>
  <li>item-23</li>
  <li>item-24</li>
  <li>item-25</li>
  <li>item-26</li>
  <li>item-27</li>
  <li>item-28</li>
  <li>item-29</li>
  <li>item-30</li>
  <li>item-31</li>
  <li>item-32</li>
  <li>item-33</li>
  <li>item-34</li>
  <li>item-35</li>
  <li>item-36</li>
  <li>item-37</li>
  <li>item-38</li>
  <li>item-39</li>
  <li>item-40</li>
  <li>item-41</li>
  <li>item-42</li>
  <li>item-43</li>
  <li>item-44</li>
  <li>item-45</li>
  <li>item-46</li>
  <li>item-47</li>
  <li>item-48</li>
  <li>item-49</li>
  <li>item-50</li>
  <li class="more-menu">....</li>
</ul>


Ответы (1 шт):

Автор решения: pheroneex

Решение на js.

const formatNav = () => {
  const containerWidth = $(".nav")[0].offsetWidth;
  const list = $(".nav li");
  list.removeClass("even");
  let isEvenLine = false;
  let currentWidthLine = 0;

  list.map((i, el) => {
    const elWidth = el.offsetWidth;
    if (elWidth + currentWidthLine < containerWidth) {
      currentWidthLine += elWidth;
    } else {
      isEvenLine = !isEvenLine;
      currentWidthLine = elWidth;
    }
    isEvenLine ? $(el).addClass("even") : null;
  });
};
formatNav();

$(window).resize(() => {
  waitForFinalEvent(
    () => {
      //reset navigation
      formatNav();
    },
    500,
    Math.random().toString(36).substr(2, 9)
  );
});

//A function that delays the execution of an event for a short period of time
const waitForFinalEvent = (() => {
  let timers = {};
  return function(callback, ms, uniqueId) {
    if (!uniqueId) {
      uniqueId = "Don't call this twice without a uniqueId";
    }
    if (timers[uniqueId]) {
      clearTimeout(timers[uniqueId]);
    }
    timers[uniqueId] = setTimeout(callback, ms);
  };
})();
body {
  margin: 0;
  padding: 0;
}

.container {
  padding: 0 15px;
}

.nav {
  width: 100%;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  box-sizing: border-box;
  overflow: hidden;
}

.nav li {
  padding-right: 40px;
  padding-bottom: 13px;
  list-style: none;
  transition: all 0.3s;
}

.nav li.even {
  transform: translateX(35px);
  color: brown;
}

.nav li.more-menu.even {
  transform: translate(35px, -20%);
}

.nav .more-menu {
  margin-left: auto;
  transform: translateY(-20%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="container">
  <ul class="nav">
    <li>item-1</li>
    <li>item-2</li>
    <li>item-3</li>
    <li>item-4</li>
    <li>item-5</li>
    <li>item-6</li>
    <li>item-7</li>
    <li>item-8</li>
    <li>item-9</li>
    <li>item-10</li>
    <li>item-11</li>
    <li>item-12</li>
    <li>item-13</li>
    <li>item-14</li>
    <li>item-15</li>
    <li>item-16</li>
    <li>item-17</li>
    <li>item-18</li>
    <li>item-19</li>
    <li>item-20</li>
    <li>item-21</li>
    <li>item-22</li>
    <li>item-23</li>
    <li>item-24</li>
    <li>item-25</li>
    <li>item-26</li>
    <li>item-27</li>
    <li>item-28</li>
    <li>item-29</li>
    <li>item-30</li>
    <li>item-31</li>
    <li>item-32</li>
    <li>item-33</li>
    <li>item-34</li>
    <li>item-35</li>
    <li>item-36</li>
    <li>item-37</li>
    <li>item-38</li>
    <li>item-39</li>
    <li>item-40</li>
    <li>item-41</li>
    <li>item-42</li>
    <li>item-43</li>
    <li>item-44</li>
    <li>item-45</li>
    <li>item-46</li>
    <li>item-47</li>
    <li>item-48</li>
    <li>item-49</li>
    <li>item-50</li>
    <li class="more-menu">....</li>
  </ul>
</div>

→ Ссылка