首页 > 解决方案 > CSS 不可预测的包装习惯

问题描述

我在一个弹性框中得到了这个简单的设置,其中包含 3 个元素。它们之间有合理的空间。中间的 .center 元素设置为 100% 的宽度。出于某种原因,无论窗口有多宽,子元素(链接)都会换行。

结果背后的机制是什么链接被包装到下一行?有足够的空间。为什么 .center div 不占用 100% 的剩余空间,所以它们不会换行。以及如何防止这种包装?

PS:我希望 .center div 占据 100% 的空间。

<div class="header">
<h1>Title</h1>
<div class="center">
  <h1>
    TEST TEXT
  </h1>
</div>
<div class="nav">
    <a>A Link</a>
    <a>Another Link</a>
    <a>A Third Link</a>
</div>

.header {
    background: #ccc; 
    display: flex;
    justify-content: space-between;
}

.nav{

  width: fit-content;
}

.center{
  width:100%;
  background: lightblue;
  text-align: center;
}

div a{
  background: tomato;
}

见这里:http: //jsfiddle.net/vsx239v1/

标签: cssflexbox

解决方案


要理解为什么你的导航元素是环绕的,你需要理解 flexbox 是如何工作的。我将用简单的话简要解释这一点,但在下面你会找到一个完整而准确的解释的参考。

最初,您已将一项设置为 100% 的宽度,并将其他所有内容保留为默认值。这里使用的重要值是:

  • flex-wrap:nowrap(默认情况下,弹性项目不会换行)
  • flex-shrink:1(默认情况下,弹性项目会缩小)
  • min-width:auto(默认情况下,弹性项目不会缩小到它们的最小内容大小

  • flex-grow:0(默认情况下,弹性项目不会增长)

在您的情况下,很明显我们有溢出,因为一个元素设置为width:100%,另一个元素设置为自动但是 flexbox 机制将缩小您的元素并将负的可用空间1分配给 flex 项目以避免溢出。

在你的情况下,第一个元素h1不能再缩小,因为它width等于它的最小内容,所以只有你的.center元素和导航会缩小,无论浏览器的大小如何,这都会发生,因为我们总是有负的可用空间,因为.center元素设置为width:100%

例如,如果您设置flex-shrink:0为 nav 元素,则不会进行换行,因为您禁用了该元素的收缩,并且所有负的可用空间都将添加到.center元素中(这可以是修复,但不是最好的)

.header {
    background: #ccc; 
    display: flex;
    justify-content: space-between;
}
h1 {
 font-size:11px;
}

.center{
  width:100%;
  background: lightblue;
  text-align: center;
}

.nav {
  flex-shrink:0;
}

div a{
  background: tomato;
}
<div class="header">
    <h1>Title</h1>
    <div class="center">
      <h1>
        TEST TEXT
      </h1>
    </div>
    <div class="nav">
        <a>A Link</a>
        <a>Another Link</a>
        <a>A Third Link</a>
    </div>
</div>

如果禁用所有元素的收缩因子,我们将出现溢出,因为不会分配负的可用空间:

.header {
    background: #ccc; 
    display: flex;
    justify-content: space-between;
}
h1 {
 font-size:11px;
}

.center{
  width:100%;
  background: lightblue;
  text-align: center;
  flex-shrink:0;
}

.nav {
  flex-shrink:0;
}

div a{
  background: tomato;
}
<div class="header">
    <h1>Title</h1>
    <div class="center">
      <h1>
        TEST TEXT
      </h1>
    </div>
    <div class="nav">
        <a>A Link</a>
        <a>Another Link</a>
        <a>A Third Link</a>
    </div>
</div>

如果您flex-wrap:wrap在容器上设置,我们将不再考虑负可用空间并缩小,就好像没有足够的空间元素将包装一样:

.header {
    background: #ccc; 
    display: flex;
    justify-content: space-between;
    flex-wrap:wrap;
}
h1 {
 font-size:11px;
}

.center{
  width:100%;
  background: lightblue;
  text-align: center;
}

div a{
  background: tomato;
}
<div class="header">
    <h1>Title</h1>
    <div class="center">
      <h1>
        TEST TEXT
      </h1>
    </div>
    <div class="nav">
        <a>A Link</a>
        <a>Another Link</a>
        <a>A Third Link</a>
    </div>
</div>


为了解决所有这些问题,您需要避免负可用空间并使总宽度不超过容器宽度。width:100%您可以考虑flex-grow允许项目增长以填充可用空间的属性,而不是使用。

.header {
    background: #ccc; 
    display: flex;
    justify-content: space-between;
}
h1 {
 font-size:11px;
}

.center{
  flex-grow:1;
  background: lightblue;
  text-align: center;
}
div a{
  background: tomato;
}
<div class="header">
    <h1>Title</h1>
    <div class="center">
      <h1>
        TEST TEXT
      </h1>
    </div>
    <div class="nav">
        <a>A Link</a>
        <a>Another Link</a>
        <a>A Third Link</a>
    </div>
</div>

这是一个很好的链接,可以更好地理解考虑所有属性的 flexbox 算法:https ://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Controlling_Ratios_of_Flex_Items_Along_the_Main_Ax


(1)负可用空间:当项目的自然大小加起来大于flex 容器中的可用空间时,我们有负可用空间。


推荐阅读