防止 flex 容器在交叉轴方向上溢出

3
在下面的示例中,我希望定位具有id child 的元素,使其右上角与具有id container 的元素的右上角相匹配。换句话说,child 应该突出到 container 的左侧和底部,并使其右边缘和顶部与 container 对齐。
然而,正如你所看到的那样,child 被压缩以匹配 container 的宽度。但并非完全如此——在第二个示例中,很明显,child 被压缩到某个限制后,开始按照所需的方式行为(即相对于 container 向左移动)。
有人能解释一下涉及这种行为的神奇力量是什么,以及我如何指定 child 不应在其内在大小以下被压缩吗?
在第三个示例中,我添加了一些不太可压缩的文本,这肯定会改善情况。不知何故,也是 flex 容器的 flex 项比常规块元素更可压缩。

  <div id="container" style="position: relative; width: 100px; height: 100px; left: 50px; border: 1px solid red">
      <div id="child" style="position: absolute; display:flex; flex-direction: column; right: 0px; border: 1px solid blue">
        <div style="
display:flex">
          <div style="flex: 1 0 auto">Long text 1</div>
          <div style="flex: 0 0 auto">Long text 2</div>
        </div>
        <div style="display:flex">
          <div style="flex: 1 0 auto">Long text 1</div>
          <div style="flex: 0 0 auto">Long text 2</div>
        </div>
      </div>
  </div>
  <hr>
  <div id="container" style="position: relative; width: 50px; height: 100px; left: 50px; border: 1px solid red">
      <div id="child" style="position: absolute; display:flex; flex-direction: column; right: 0px; border: 1px solid blue">
        <div style="
display:flex">
          <div style="flex: 1 0 auto">Long text 1</div>
          <div style="flex: 0 0 auto">Long text 2</div>
        </div>
        <div style="display:flex">
          <div style="flex: 1 0 auto">Long text 1</div>
          <div style="flex: 0 0 auto">Long text 2</div>
        </div>
      </div>
  </div>
  <hr>
  <div id="container" style="position: relative; width: 50px; height: 100px; left: 50px; border: 1px solid red">
      <div id="child" style="position: absolute; display:flex; flex-direction: column; right: 0px; border: 1px solid blue">
        <div style="white-space: nowrap;">This is just&nbsp;ridiculous</div>
        <div style="
display:flex">
          <div style="flex: 1 0 auto">Long text 1</div>
          <div style="flex: 0 0 auto">Long text 2</div>
        </div>
        <div style="display:flex">
          <div style="flex: 1 0 auto">Long text 1</div>
          <div style="flex: 0 0 auto">Long text 2</div>
        </div>
      </div>
  </div>


我认为你的问题归结为希望布局向左溢出。在从左到右的文本方向中,这是不可能的,因为HTML / CSS中的overflow只能发生在文本方向上(否则就不是溢出)。https://dev59.com/Hpnga4cB1Zd3GeqPYnGF#38830775 - Michael Benjamin
1个回答

2
有点棘手的解释,但这里绝对元素的shrink-to-fit行为控制着您元素的宽度。根据规范,我们有以下内容:

计算收缩到适合宽度的宽度类似于使用自动表格布局算法计算表格单元格的宽度。粗略地说:通过格式化内容而不打破除显式换行符以外的任何行来计算首选宽度,并且还计算首选最小宽度,例如,通过尝试所有可能的换行符。 CSS 2.1没有定义确切的算法。第三步,计算可用宽度:在将“left”(情况1)或“right”(情况3)设置为0后,通过解决“width”找到它。

然后,收缩到适合宽度是:min(max(preferred minimum width, available width), preferred width)

关键在于首选最小宽度,这是最小边界。
为了更好地理解,让我们删除一些属性:

#container {
  animation:change 5s linear infinite alternate;
}

@keyframes change {
  from {
    width:300px;
  }
  to {
    width:50px;
  }
}
<div id="container" style="position: relative; height: 100px; left: 50px; border: 1px solid red">
      <div id="child" style="position: absolute; display:flex; flex-direction: column; right: 0px; border: 1px solid blue">
        <div style="
display:flex">
          <div style="/*flex: 1 0 auto*/">Long text 1</div>
          <div style="/*flex: 0 0 auto*/">Long text 2</div>
        </div>
  
      </div>
  </div>

你可以清楚地看到绝对定位元素将适应其内容(首选宽度),当空间较少时,文本将开始换行,直到达到首选最小宽度,元素将停止收缩。这就是你所拥有的限制。
添加flex属性将不会改变任何东西,因为这些属性不会影响其父元素的宽度行为,但它们将考虑该宽度以进行所需的计算(增长、收缩等)。
最初的回答:绝对定位元素的宽度受限于其内容和最小宽度。Flex属性不会影响其父元素的宽度行为,但会在计算时考虑该宽度。

#container {
  animation:change 5s linear infinite alternate;
}

@keyframes change {
  from {
    width:300px;
  }
  to {
    width:50px;
  }
}
<div id="container" style="position: relative; height: 100px; left: 50px; border: 1px solid red">
      <div id="child" style="position: absolute; display:flex; flex-direction: column; right: 0px; border: 1px solid blue">
        <div style="
display:flex">
          <div style="/*flex: 1 0 auto*/">Long text 1</div>
          <div style="/*flex: 0 0 auto*/">Long text 2</div>
        </div>
  
      </div>
  </div>
  <div id="container" style="position: relative; height: 100px; left: 50px; border: 1px solid red">
      <div id="child" style="position: absolute; display:flex; flex-direction: column; right: 0px; border: 1px solid blue">
        <div style="
display:flex">
          <div style="flex: 1 0 auto">Long text 1</div>
          <div style="flex: 0 0 auto">Long text 2</div>
        </div>
  
      </div>
  </div>

你可以清楚地注意到在这两种情况下我们的宽度是相同的,而在第二个示例中,我们只是告诉元素不要收缩,因此会出现溢出:
在您的第三个示例中,通过添加white-space: nowrap;,您只是增加了首选最小宽度,因为您禁用了换行符,因此浏览器将考虑首选最小宽度等于首选宽度:

#container {
  animation:change 5s linear infinite alternate;
}

@keyframes change {
  from {
    width:300px;
  }
  to {
    width:50px;
  }
}
<div id="container" style="position: relative; height: 100px; left: 50px; border: 1px solid red">
      <div id="child" style="position: absolute; display:flex; flex-direction: column; right: 0px; border: 1px solid blue">
        <div style="
display:flex;white-space:nowrap">
          <div style="/*flex: 1 0 auto*/">Long text 1</div>
          <div style="/*flex: 0 0 auto*/">Long text 2</div>
        </div>
  
      </div>
  </div>
  <div id="container" style="position: relative; height: 100px; left: 50px; border: 1px solid red">
      <div id="child" style="position: absolute; display:flex; flex-direction: column; right: 0px; border: 1px solid blue">
        <div style="
display:flex;white-space:nowrap">
          <div style="flex: 1 0 auto">Long text 1</div>
          <div style="flex: 0 0 auto">Long text 2</div>
        </div>
  
      </div>
  </div>

由于您正在使用flexbox,您可以调整对齐方式以控制文本的溢出并使其位于左侧:

#container {
  animation:change 5s linear infinite alternate;
}

@keyframes change {
  from {
    width:300px;
  }
  to {
    width:50px;
  }
}
  <div id="container" style="position: relative; height: 100px; left: 50px; border: 1px solid red">
      <div id="child" style="position: absolute; display:flex; flex-direction: column; right: 0px; border: 1px solid blue">
        <div style="
display:flex;justify-content:flex-end;">
          <div style="flex: 1 0 auto">Long text 1</div>
          <div style="flex: 0 0 auto">Long text 2</div>
        </div>
  
      </div>
  </div>

如何指定子元素不应压缩到其固有大小以下?

问题在于子元素(绝对定位元素)没有任何固有大小,其大小是由收缩适合算法定义的。您唯一的方法是确保首选最小宽度足够大,以避免任何不必要的收缩(例如使用white-space:nowrap)。

Original Answer翻译成“最初的回答”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接