【问题标题】:Limit the width of flex items on hover to their initial width将悬停时弹性项目的宽度限制为初始宽度
【发布时间】: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。也许我错了。

标签: css flexbox


【解决方案1】:

您可以简单地通过在 .flex 上使用 CSS grid-box 并将 grid-template-columns 设置为 repeat(5, 1fr) 来解决这个问题,这将重复 5 个相等的列,如果您不想要相等的列,您可以指定宽度每个都喜欢100px 120px 320px ...,但要确保它们的总和不大于其父级。

示例

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: grid;
  grid-template-columns: repeat(5, 1fr);
}

.flex-item {
  border: 1px solid black;
  border-right: 0;
}

.flex-item:last-child {
  border-right: 1px solid black;
}

.flex-item ul {
  background-color: yellow;
  display: none;
  max-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>

【讨论】:

  • 参考问题中的cmets。 OP 不想要大小相等的列。我怀疑固定宽度也不是一种选择。
  • 我在上面的描述中提到过,如果他不想要,他可以手动设置宽度
  • 我认为可以公平地假设如果这是一个选项,OP 就不会发布这个问题,因为它是最简单的解决方案。
  • 我尝试了所有方法,例如更改flex-basisflex-growflex-shrink,我还支付了max-widthmin-width,但没有任何解决方法ul a 仍在扩展鼠标悬停事件但grid 制作固定列,以便在悬停ul a 时不会扩展@
  • 使用flex-basis: 0; flex-grow: 1,flex 也可以使用固定宽度的列。切换到电网没有明显的好处。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-20
  • 1970-01-01
  • 2018-05-07
  • 2018-05-22
  • 2011-04-16
  • 2021-09-06
  • 2012-08-07
相关资源
最近更新 更多