我需要设计一个由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中运行
答案 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;
}