【问题标题】:Is it possible to shrinkwrap flex items with wrapping text inside them?是否可以在其中包含包装文本的收缩包装弹性项目?
【发布时间】:2023-12-18 07:53:01
【问题描述】:

我有一个不起眼的导航菜单:

<div>
    <ul>
        <li><a href="/real-estate"><span>Real Estate &amp;&nbsp;Development</span></a></li>
        <li><a href="/new-business"><span>New &amp; Expanding Business</span></a></li>
        { … }
    </ul>
</div>

此菜单需要以下视觉属性:

  • 项目在其容器中水平分布,在它们之间放置相等的空间
  • 项目中的文本可以换行以减少项目占用的水平空间
  • 所有文本都垂直居中。

我不能同时得到这三个。

这个 SCSS:

div > ul {
    display: flex;
    justify-content: space-between;

    > li {
        display: table;
        table-layout: fixed;
        word-wrap: break-word;

        > a {
            display: table-cell;
            text-align: center;
            vertical-align: middle;
        }
    }
}

...通过垂直居中使我得到很大的间距,但文本不换行,所以项目溢出容器:

如果我删除 display: table 的东西:

div > ul {
    display: flex;
    justify-content: space-between;

    > li {
        // DELETED display: table;
        // DELETED table-layout: fixed;
        word-wrap: break-word;

        > a {
            display: table-cell;
            text-align: center;
            vertical-align: middle;
        }
    }
}

...然后我得到了很好的文本换行,但项目之间的间距全部关闭:

我尝试了许多其他 CSS 属性组合,但没有什么比这两个更接近我了。 Here's a pen with my code. 有没有什么咒语可以让我从这个菜单中得到我想要的所有东西?

编辑:我的笔现在包括第三次尝试,它使用另一个 Flex 容器而不是显示:table-cell。间距更好,但仍然不是很好。我想这可能归结为in this answer 描述的文本换行宽度问题,我可能只需要硬编码一些换行符或使用 JavaScript。

编辑 2:不过,问题在于这些项目并没有在设定的大小上达到最大值。在我在那里的第三次尝试中,那些换行并最终大于换行文本宽度的 not 最终彼此大小相同。事实上,space-between 并没有做任何事情,因为顶层的弹性项目填满了整个空间。它们之间的空间是 0px。

【问题讨论】:

  • 在最后一个示例中,看起来之间的间距很好。你的意思是你希望每个项目都有相同的宽度吗?即“Real Estate & Development”“Global”的宽度相同?
  • 它们之间的间距根本不相等。查看左边缘到第一个项目间距和最后一个项目到右边缘之间的差异。看看前两项之间的差距与 Global 和 Career Center 之间的差距。
  • 那么在等宽问题上是“否”吗?为什么需要display: table
  • display: table 使间距均匀,但不允许换行。删除它允许换行,但会使间距变窄。是的,我不希望它们具有相同的宽度,我希望它们均匀分布,就像justify-content: space-between 应该做的那样。但是请参阅我对我的问题的编辑,了解为什么我可能会大发雷霆。
  • 是的,那个编辑帖子看起来像你的问题。即使您没有设置最大宽度,文本在换行后也不会重新调整大小。

标签: html css flexbox centering display


【解决方案1】:

a 元素上使用flex 而不是table-cell,然后width: min-content 放在其中的spans 上

div > ul {
    display: flex;
    justify-content: space-between;

    > li > a {
        display: flex;
        align-items: center;
        justify-content: center;
        text-align: center;

        span {
            width: min-content;
        }
    }
}

您可能会获得比您想要的更多的文本换行,但您可以使用不间断空格来控制它。

【讨论】:

    【解决方案2】:

    文本应该已经在弹性项目中自动换行。它使用以下代码为我工作:

    SCSS:

    ul {
      padding: 0;
      list-style: none;
      display: flex;
      background-color: grey;
      height: 50px;
      align-items: center;
      justify-content: space-between;
      li {
        text-align: center;
        flex: 1;
      }
    }
    

    HTML:

    <div>
        <ul>
            <li><a href="/real-estate"><span>Real Estate &amp;&nbsp;Development</span></a></li>
            <li><a href="/new-business"><span>New &amp; Expanding Business</span></a></li>
          <li><a href="/new-business"><span>New &amp; Expanding Business</span></a></li>
        </ul>
    </div>
    

    Fiddle

    您可以使用justify-content调整项目之间的间距:

    .container {
      justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
    }
    

    cssTricks page for Flexbox

    您可以通过在 li 元素上设置 flex-basis: 0; flex-grow: 1; 使项目具有相等的宽度。

    【讨论】:

    • 您的小提琴没有足够不同大小的导航项目来查看不均匀的间距。 Here's a fork that does.
    • 刚刚更新。我认为将flex-basis: 0; flex-grow: 1; 添加到您的li 元素应该可以解决间距问题。
    • 不幸的是,这在我的实际网站或in my pen (Attempt Five) 上没有得到很好的结果。
    • @75thTrombone 尝试将display: tableli 分开