равноудаленный разделитель между гибкими элементами с переменной шириной - PullRequest
0 голосов
/ 28 октября 2018

Мне нужно спроектировать навигацию, динамически отображаемую CMS (поэтому я не контролирую разметку HTML).В меню есть неизвестное, переменное количество элементов, а все элементы имеют переменную, неизвестную ширину.Мне нужно расположить эти пункты меню в одну строку с равноудаленным интервалом между ними (это легко сделать с помощью flexbox) и с визуальным разделителем точно в середине интервала (это моя нерешенная проблема).

Нижекод, который я получил до сих пор.HTML - это просто пример вывода, и я не могу его изменить.Мне также не разрешено использовать JS.CSS от меня, и я могу полностью контролировать его.

.mainnav {
  width: 100%;
  display: flex;
  justify-content: space-between;
  list-style-type: none;
  margin: 0;
  padding: 0;
  border: 1px solid black;
}

.mainnav__item {
  flex: 0 0 auto;
  background-color: yellow;
  position: relative;
  white-space: nowrap;
}

.mainnav__item + .mainnav__item::before {
  content: '';
  width: 1px;
  height: 100%;
  background-color: red;
  position: absolute;
  left: -50%;
  top: 0;
}
<ul class="mainnav">
  <li class="mainnav__item">
    <a class="mainnav__link" href="#">Short</a>
  </li>
  <li class="mainnav__item">
    <a class="mainnav__link" href="#">Looooooooooooooong</a>
  </li>
  <li class="mainnav__item">
    <a class="mainnav__link" href="#">Mediuuum</a>
  </li>
  <li class="mainnav__item">
    <a class="mainnav__link" href="#">whatever else</a>
  </li>
</ul>

Моя проблема - красная разделительная линия.Оно должно быть точно посередине, но я не знаю, как рассчитать горизонтальное положение.

Кто-нибудь может мне сказать, что решение для размещения разделителя только на CSS?

Решение должно работатьв распространенных современных браузерах (текущая версия [Android | Win] Chrome, [macOs | iOs] Safari, Firefox, Edge), а также в IE11

1 Ответ

0 голосов
/ 28 октября 2018

Одной из идей является рассмотрение display:contents; 1 внутри элемента li и сохранение псевдоэлемента в потоке (удалить position:absolute).Это сделает псевдоэлемент и a гибкими элементами вместо элемента li, поэтому space-between выполнит свою работу.

Просто обратите внимание на поддержку браузера так как это новая функция.

.mainnav {
  width: 100%;
  display: flex;
  justify-content: space-between;
  list-style-type: none;
  margin: 0;
  padding: 0;
  border: 1px solid black;
}

.mainnav__item {
  flex: 0 0 auto;
  position: relative;
  white-space: nowrap;
  display:contents;
}
.mainnav__item a {
  background:yellow;
}

.mainnav__item + .mainnav__item::before {
  content: '';
  width: 1px;
  display:block;
  background-color: red;
}
<ul class="mainnav">
  <li class="mainnav__item">
    <a class="mainnav__link" href="#">Short</a>
  </li>
  <li class="mainnav__item">
    <a class="mainnav__link" href="#">Looooooooooooooong</a>
  </li>
  <li class="mainnav__item">
    <a class="mainnav__link" href="#">Mediuuum</a>
  </li>
  <li class="mainnav__item">
    <a class="mainnav__link" href="#">whatever else</a>
  </li>
</ul>

1 Сам элемент не создает никаких блоков , ноего дочерние элементы и псевдоэлементы по-прежнему генерируют блоки и текст работает как обычно.В целях генерации и макета блока элемент должен обрабатываться как , если он был заменен в дереве элементов его содержимым (включая исходный документ children и псевдоэлементов , таких как псевдоэлементы :: before и :: after, которые генерируются до / после дочерних элементов элемента как обычно). ref

Другая идея состоит в том, чтобы настроить flex-grow и использовать границу вместо того, чтобы полагаться на space-between:

.mainnav {
  display: flex;
  list-style-type: none;
  margin: 0;
  padding: 0;
  border: 1px solid black;
}

.mainnav__item {
  flex: 0 0 auto;
  position: relative;
  white-space: nowrap;
  flex-grow:2; /*middle elements need to grow twice that edge element*/
  text-align:center;
  border-left:1px solid red;
  border-right:1px solid red;
}
.mainnav__item a {  
background:yellow;
}
.mainnav__item:first-child {
  flex-grow:1;
  text-align:left;
  border-left:none;
}
.mainnav__item:last-child { 
  flex-grow:1;
  text-align:right;
  border-right:none;
}
<ul class="mainnav">
  <li class="mainnav__item">
    <a class="mainnav__link" href="#">Short</a>
  </li>
  <li class="mainnav__item">
    <a class="mainnav__link" href="#">Looooooooooooooong</a>
  </li>
  <li class="mainnav__item">
    <a class="mainnav__link" href="#">Mediuuum</a>
  </li>
  <li class="mainnav__item">
    <a class="mainnav__link" href="#">whatever else</a>
  </li>
</ul>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...