【发布时间】:2020-12-25 20:56:15
【问题描述】:
在下面的演示中,当 Item 3 悬停在上面时,显示内容中略长的链接使 Item 3 宽度扩大:
ul, li, a {
color: black;
display: block;
font-family: sans-serif;
margin: 0;
list-style-type: none;
overflow-wrap: break-word;
padding: 0;
text-decoration: none;
}
.container {
background-color: lightgrey;
width: 450px;
}
.flex {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
.flex-item {
border: 1px solid black;
border-right: 0;
flex-basis: auto;
flex-grow: 1;
flex-shrink: 0;
position: relative;
}
.flex-item:last-child {
border-right: 1px solid black;
flex-grow: 0;
}
.flex-item ul {
background-color: yellow;
display: none;
width: 100%;
}
.flex-item:hover ul {
display: block;
}
.flex-item a {
padding: 10px;
}
.flex-item ul a {
padding: 0 10px;
}
.flex-item ul a:hover {
background-color: lime;
}
<div class="container">
<ul class="flex">
<li class="flex-item">
<a href="#">Item 1</a>
<ul>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
</ul>
</li>
<li class="flex-item">
<a href="#">Item 2</a>
<ul>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
</ul>
</li>
<li class="flex-item">
<a href="#">Item 3</a>
<ul>
<li><a href="#">Short</a></li>
<li><a href="#">A little bit longer</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
</ul>
</li>
<li class="flex-item">
<a href="#">Item 4</a>
<ul>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
</ul>
</li>
<li class="flex-item">
<a href="#">Item 5</a>
<ul>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
</ul>
</li>
</ul>
</div>
这种行为是不可取的,理想情况下,我希望将较长的链接限制为弹性项目的初始宽度,必要时通过换行到多行。
我知道这可以通过在 flex 项目的内容上设置 position: absolute 轻松实现,但这具有将内容移出灰色容器 div 的不良副作用,这意味着黑色边框和灰色背景不再当项目悬停时展开:
ul, li, a {
color: black;
display: block;
font-family: sans-serif;
margin: 0;
list-style-type: none;
overflow-wrap: break-word;
padding: 0;
text-decoration: none;
}
.container {
background-color: lightgrey;
width: 450px;
}
.flex {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
.flex-item {
border: 1px solid black;
border-right: 0;
flex-basis: auto;
flex-grow: 1;
flex-shrink: 0;
position: relative;
}
.flex-item:last-child {
border-right: 1px solid black;
flex-grow: 0;
}
.flex-item ul {
background-color: yellow;
display: none;
position: absolute;
width: 100%;
}
.flex-item:hover ul {
display: block;
}
.flex-item a {
padding: 10px;
}
.flex-item ul a {
padding: 0 10px;
}
.flex-item ul a:hover {
background-color: lime;
}
<div class="container">
<ul class="flex">
<li class="flex-item">
<a href="#">Item 1</a>
<ul>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
</ul>
</li>
<li class="flex-item">
<a href="#">Item 2</a>
<ul>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
</ul>
</li>
<li class="flex-item">
<a href="#">Item 3</a>
<ul>
<li><a href="#">Short</a></li>
<li><a href="#">A little bit longer</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
</ul>
</li>
<li class="flex-item">
<a href="#">Item 4</a>
<ul>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
</ul>
</li>
<li class="flex-item">
<a href="#">Item 5</a>
<ul>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
<li><a href="#">Short</a></li>
</ul>
</li>
</ul>
</div>
有没有一种纯 CSS 的方式来获得两者的最佳效果,通过包装 flex 项目内容和扩展容器?
注意 1: 可能存在可变数量的具有不同文本长度的父项,并且每个父项之间必须始终保持相等的间距。因此,恐怕任何将所有项目设置为相等宽度的解决方案都是不可接受的。
注意 2:该行中的最后一项不应在文本后添加任何空白。
另外,如果有什么方法可以在没有 flexbox 的情况下实现这种布局,我愿意接受建议。
【问题讨论】:
-
在弹性项目上用
flex-basis: 0代替flex-basis: auto怎么样? -
@MichaelBenjamin 感谢您的建议,但不幸的是,这会将所有项目更改为等宽,而我需要它们等距,初始宽度可能不同。
-
使用
flex-basis: auto,您将宽度设置为内容长度。因此,自然地,该项目将在悬停时展开以适应下拉文本的长度。 -
max-width和 grid 由于上述相同的原因也无法工作。 -
我认为,在这一点上,您唯一的选择是固定宽度或 JS。也许我错了。