【问题标题】:Setting wrapper div to position absolute shrinks wrapper to arbitrary width将包装器 div 设置为绝对位置会将包装器缩小到任意宽度
【发布时间】:2020-11-13 19:50:50
【问题描述】:

我遇到了position: absolute 的问题,我在任何地方都找不到解释为什么会发生的答案。

我在包装器中有一个 flexbox 容器,其中有两个子级,每个子级都设置为 flex-basis: 50%。当我在包装器 div 上设置 position: absolute 时,包装器会以不可预知的方式收缩。

请看下面的代码:

.outer-wrapper {
  position: relative;
  width: 100%;
}
.outer-wrapper .wrapper {
  position: absolute;
}
.outer-wrapper .wrapper .flex-container {
  display: flex;
}
.outer-wrapper .wrapper .flex-container .flex-item {
  flex-basis: 50%;
}
<div class="outer-wrapper">

  <div class="wrapper">

    <div class="flex-container">

      <div class="flex-item">
         Some Text That Is Long
      </div>

      <div class="flex-item">
         Some Text
      </div>

    </div>

    <div class="flex-container">

      <div class="flex-item">
         Some Text
      </div>

      <div class="flex-item">
         Some Text
      </div>

    </div>

  </div>
  
</div>

删除 CSS 中的第 6 行会导致 flex-container 扩展到父级的全宽,并且每个 flex 子级占用 50% 的宽度,正如预期的那样。但是,当我将包装器 div 设置为 position: absolute 时,包装器 div 会缩小到任意宽度,并且 flex-children 中的文本会分成多行。

我的问题:

  • 为什么在包装 div 上设置 position: absolute 会导致包装 div 缩小到小于其内容?
  • 浏览器如何确定将包装 div 缩小到什么宽度?在我看来,它要么缩小到尽可能小而不在文本中引入换行符,要么缩小到尽可能小,同时仍然适合最长的单词,而是缩小到中间的某个地方(它只引入一串短单词中的一个换行符)。
  • 有没有办法,在仍然以这种方式使用 flexbox 和 position: absolute 时,强制浏览器不将包装器缩小到小于其内容(除非包装器上设置了最大宽度)?

非常感谢任何帮助!这让我发疯了!

【问题讨论】:

    标签: css flexbox css-position


    【解决方案1】:

    为什么在 wrapper div 上设置 position: absolute 会导致 wrapper div 缩小到小于其内容?

    浏览器如何确定将包装器 div 缩小到什么宽度?

    诀窍是使用flex-basis::50%。您处于使用收缩以适应容器(position:absolute 元素)的情况,同时您在 flex-basis 中使用百分比值。所以浏览器首先计算容器的宽度(忽略flex-basis)然后计算的宽度将作为flex-basis的参考。

    下面是正在发生的事情的说明:

    .wrapper {
      position: absolute;
      border:1px solid red;
    }
    
     .wrapper .flex-container {
      display: flex;
    }
    
     .wrapper .flex-container .flex-item {
      /*flex-basis: 50%;*/
      border:1px solid green;
    }
    <div class="wrapper">
      <div class="flex-container">
    
        <div class="flex-item">
          Some Text That Is Long
        </div>
    
        <div class="flex-item">
          Some Text
        </div>
    
      </div>
    
      <div class="flex-container">
    
        <div class="flex-item">
          Some Text
        </div>
    
        <div class="flex-item">
          Some Text
        </div>
    
      </div>
    </div>
    
    <div class="wrapper" style="top:100px;">
      <div class="flex-container">
    
        <div class="flex-item" style="flex-basis: 50%;">
          Some Text That Is Long
        </div>
    
        <div class="flex-item" style="flex-basis: 50%;">
          Some Text
        </div>
    
      </div>
    
      <div class="flex-container">
    
        <div class="flex-item" style="flex-basis: 50%;">
          Some Text
        </div>
    
        <div class="flex-item" style="flex-basis: 50%;">
          Some Text
        </div>
    
      </div>
    </div>

    请注意在第一个示例中(没有 flex-basis)宽度如何等于最大内容。在第二个示例中,您将看到总宽度没有改变,但我们使弹性项目的宽度相等。

    inline-blockfloat 或任何收缩以适应容器也会发生相同的逻辑。

    .wrapper {
      display:inline-block;
      border:1px solid red;
    }
    
     .wrapper .flex-container {
      display: flex;
    }
    
     .wrapper .flex-container .flex-item {
      /*flex-basis: 50%;*/
      border:1px solid green;
    }
    <div class="wrapper">
      <div class="flex-container">
    
        <div class="flex-item">
          Some Text That Is Long
        </div>
    
        <div class="flex-item">
          Some Text
        </div>
    
      </div>
    
      <div class="flex-container">
    
        <div class="flex-item">
          Some Text
        </div>
    
        <div class="flex-item">
          Some Text
        </div>
    
      </div>
    </div>
    <br><br>
    <div class="wrapper">
      <div class="flex-container">
    
        <div class="flex-item" style="flex-basis: 50%;">
          Some Text That Is Long
        </div>
    
        <div class="flex-item" style="flex-basis: 50%;">
          Some Text
        </div>
    
      </div>
    
      <div class="flex-container">
    
        <div class="flex-item" style="flex-basis: 50%;">
          Some Text
        </div>
    
        <div class="flex-item" style="flex-basis: 50%;">
          Some Text
        </div>
    
      </div>
    </div>

    要得到你想要的,很明显你不需要使用flex-basis:50% 并考虑不同的想法来获得相同的宽度。

    这是一个使用 CSS 网格的,因为我认为使用 flexbox 会很乏味:

    .wrapper {
      position:absolute;
      border:1px solid red;
    }
    
     .wrapper .flex-container {
      display: grid;
      grid-template-columns:repeat(2,1fr);
    }
    
     .wrapper .flex-container .flex-item {
      border:1px solid green;
    }
    <div class="wrapper">
      <div class="flex-container">
        <div class="flex-item">
          Some Text That Is Long
        </div>
    
        <div class="flex-item">
          Some Text
        </div>
    
      </div>
      <div class="flex-container">
    
        <div class="flex-item">
          Some Text
        </div>
    
        <div class="flex-item">
          Some Text
        </div>
    
      </div>
    </div>

    【讨论】:

      【解决方案2】:

      它缩小的原因是因为您在没有指定宽度的情况下设置绝对位置。

      当元素被绝对定位时,将不支持具有父内容区域全宽的块元素特性。

      如果要保留块元素的宽度(容器的100%),那么将绝对元素.wrapper的宽度设置为100%,问题就解决了。

      .outer-wrapper {
         position: relative;
         width: 100%;
      }
      
      .wrapper {
         position: absolute; 
         width:100%;
      }
      
      .flex-container {
         display: flex;
      }
      
      .flex-item {
         flex-basis: 50%;
      }
      

      【讨论】:

      • 感谢您的回复!这一切都说得通。但是,如果我不想保留块元素的宽度(我不希望包装器是其父级的全宽),但希望包装器增长到足以容纳其内容,我该怎么办没有在文本中强制换行?另外,如果未明确设置宽度(我的问题的第 2 部分),您能否帮助我了解浏览器如何确定包装器的宽度?感谢您的帮助!
      • 如果是这样,请删除flex-basis 或让我知道您要完成什么,以便我帮助您实现它。当没有任何东西可以告诉浏览器如何切片时,你想通过将其设置为 50% 来做什么。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-22
      • 1970-01-01
      • 2020-12-05
      • 1970-01-01
      • 2011-09-30
      • 2013-05-02
      • 2014-05-02
      相关资源
      最近更新 更多