可变宽度的弹性项目之间的等距定界符

时间:2018-10-28 12:19:36

标签: css css3 flexbox

我需要设计一个由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 :(得分:2)

一个想法是考虑在display:contents;元素内使用li 1 并保持伪元素的流入(删除{{1} }。这将使伪元素和position:absolute成为弹性项目,而不是a元素,因此li将完成工作。

只需注意browser support,因为它是一项新功能。

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;
}

  

1 元素本身不生成任何框,但其子元素和   伪元素仍会生成框,并且文本照常运行。为了   出于生成和布局框的目的,必须将元素视为   如果已在元素树中被其内容替换(包括   源文档子级和其伪元素,例如   :: before和:: after伪元素,它们在之前/之后生成   元素的子元素)。 ref

另一种想法是调整<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>并使用边框而不是依靠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;
}