【问题标题】:Make absolute positioned div expand parent div height使绝对定位的 div 扩展父 div 高度
【发布时间】:2012-08-17 17:41:19
【问题描述】:

正如您在下面的 CSS 中所见,我希望 child2 将自己定位在 child1 之前。这是因为我目前正在开发的网站也应该在移动设备上运行,child2 应该在底部,因为它包含我想要的导航,位于移动设备上的内容下方。 - 为什么不是 2 个母版页?这是在整个 HTML 中重新定位的唯一 2 个divs,因此这个微小更改的 2 个母版页是多余的。

HTML:

<div id="parent">
    <div class="child1"></div>
    <div class="child2"></div>
</div>

CSS:

parent { position: relative; width: 100%; }
child1 { width: auto; margin-left: 160px; }
child2 { width: 145px; position: absolute; top: 0px; bottom: 0px; }

child2 具有动态高度,因为不同的子站点可能有更多或更少的导航项。

我知道绝对定位的元素会从流中移除,因此会被其他元素忽略。
我尝试在父 div 上设置 overflow:hidden;,但这没有帮助,clearfix 也没有。

我最后的手段是 JavaScript 来相应地重新定位两个 divs,但现在我会尝试看看是否存在非 JavaScript 的方式来执行此操作。

【问题讨论】:

  • 我不是 100% 确定,但我认为您可能必须采用 JS 解决方案来计算 child2 的高度并相应地移动 child1。
  • 这可以通过将父位置设置为相对而子位置设置为绝对来完成。
  • 看看这个Workaround也许能帮上忙。
  • 如果父级是相对的,子级是绝对的,并且您希望将子级定位在底部(即父级的高度),只需使用 top:100%。

标签: html css position master-pages parent-child


【解决方案1】:

您自己回答了这个问题:“我知道绝对定位的元素已从流中删除,因此被其他元素忽略。”所以你不能根据绝对定位的元素来设置父母的高度。

你要么使用固定高度,要么需要 JS。

【讨论】:

  • 我将其标记为从技术上讲是正确的方法,尽管我找到了解决我的问题的另一种方法,实际上是将所需的 css 嵌套在必须区分的特定页面上(2 出目前有 40 个)。
  • 只是在想...如果它真的不合时宜,那么父元素的左填充怎么会影响绝对定位的子元素?
  • @user557419 如果您找到其他解决方案,请将其放在答案中
  • 您好,我尝试在 React 中添加一个 Javascript 来调整父级高度,但是卡住了,您知道吗? stackoverflow.com/questions/69498478/…
【解决方案2】:

虽然使用position: absolute 拉伸到元素是不可能的,但通常有一些解决方案可以在获得相同效果的同时避免绝对定位。看看这个在你的特殊情况下解决问题的小提琴 http://jsfiddle.net/gS9q7/

诀窍是通过浮动两个元素来反转元素顺序,第一个向右,第二个向左,所以第二个首先出现。

.child1 {
    width: calc(100% - 160px);
    float: right;
}
.child2 {
    width: 145px;
    float: left;
}

最后,为父节点添加一个 clearfix 就完成了(请参阅fiddle 了解完整的解决方案)。

通常,只要具有绝对位置的元素位于父元素的顶部,您就很有可能通过浮动元素找到解决方法。

【讨论】:

    【解决方案3】:

    有一个非常简单的方法可以解决这个问题。

    您只需在相对 div 中复制 child1 和 child2 的内容,在父 div 中使用 display:none。说 child1_1 和 child2_2。将 child2_2 放在顶部,将 child1_1 放在底部。

    当您的 jquery(或其他)调用绝对 div 时,只需使用 display:block AND visibility:hidden 设置相应的相对 div(child1_1 或 child2_2)。相对子级仍然不可见,但会使父级的 div 更高。

    【讨论】:

    • 这让我想到了正确的方向。在我的情况下,设置 display: none on the "size holder" content 使 div 不是大小,但是 opacity: 0,正确调整 div 的大小并且不需要任何额外的 jquery。
    • 我的方法是获取两个重复的 div,第一个是绝对位置的可见内容,第二个是隐藏可见性的 div,它使父 div 保持正确的高度一切正常=D
    【解决方案4】:

    Feeela 是对的,但是如果您像这样颠倒您的 div 定位,您可以让父 div 收缩或扩展为子元素:

    .parent {
        position: absolute;
        /* position it in the browser using the `left`, `top` and `margin` 
           attributes */
    }
    
    .child {
        position: relative;
        height: 100%;
        width: 100%;
    
        overflow: hidden;
        /* to pad or move it around using `left` and `top` inside the parent */
    }
    

    这应该适合你。

    【讨论】:

      【解决方案5】:

      这个问题是在 2012 年 flexbox 之前提出的。使用现代 CSS 解决这个问题的正确方法是使用媒体查询和移动设备的弹性列反转。不需要绝对定位。

      https://jsfiddle.net/tnhsaesop/vjftq198/3/

      HTML:

      <div class="parent">
        <div style="background-color:lightgrey;">
          <p>
            I stay on top on desktop and I'm on bottom on mobile
          </p>
        </div>
        <div style="background-color:grey;">
          <p>
            I stay on bottom on desktop and I'm on top on mobile
          </p>
        </div>
      </div>
      

      CSS:

      .parent {
        display: flex;
        flex-direction: column;
      }
      
      @media (max-width: 768px) {
        .parent {
          flex-direction: column-reverse;
        }
      }
      

      【讨论】:

      • 您也可以在第一项上使用order: 2,例如,如果有很多选项并且前面需要此特定选项。
      【解决方案6】:

      使用纯 JavaScript,您只需要使用 getComputedStyle() 方法检索 static position 子元素 .child1 的高度,然后将该检索值设置为相同的 padding-top使用 HTMLElement.style 属性的孩子。


      检查并运行以下 代码片段,以获得我上面描述的实际示例:

      /* JavaScript */
      
      var child1 = document.querySelector(".child1");
      var parent = document.getElementById("parent");
      
      var childHeight = parseInt(window.getComputedStyle(child1).height) + "px";
      child1.style.paddingTop = childHeight;
      /* CSS */
      
      #parent { position: relative; width: 100%; }
      .child1 { width: auto; }
      .child2 { width: 145px; position: absolute; top: 0px; bottom: 0px; }
      html, body { width: 100%;height: 100%; margin: 0; padding: 0; }
      <!-- HTML -->
      
      <div id="parent">
          <div class="child1">STATIC</div>
          <div class="child2">ABSOLUTE</div>
      </div>

      【讨论】:

        【解决方案7】:

        有一个非常简单的 hack 可以解决这个问题

        这是一个说明解决方案的代码框:https://codesandbox.io/s/00w06z1n5l

        HTML

        <div id="parent">
          <div class="hack">
           <div class="child">
           </div>
          </div>
        </div>
        

        CSS

        .parent { position: relative; width: 100%; }
        .hack { position: absolute; left:0; right:0; top:0;}
        .child { position: absolute; left: 0; right: 0; bottom:0; }
        

        您可以使用 hack div 的定位来影响孩子自己定位的位置。

        这是一个 sn-p:

        html {
          font-family: sans-serif;
          text-align: center;
        }
        
        .container {
          border: 2px solid gray;
          height: 400px;
          display: flex;
          flex-direction: column;
        }
        
        .stuff-the-middle {
          background: papayawhip
            url("https://camo.githubusercontent.com/6609e7239d46222bbcbd846155351a8ce06eb11f/687474703a2f2f692e696d6775722e636f6d2f4e577a764a6d6d2e706e67");
          flex: 1;
        }
        
        .parent {
          background: palevioletred;
          position: relative;
        }
        
        .hack {
          position: absolute;
          left: 0;
          top:0;
          right: 0;
        }
        .child {
          height: 40px;
          background: rgba(0, 0, 0, 0.5);
          position: absolute;
          bottom: 0;
          left: 0;
          right: 0;
        }
            <div class="container">
              <div class="stuff-the-middle">
                I have stuff annoyingly in th emiddle
              </div>
              <div class="parent">
                <div class="hack">
                  <div class="child">
                    I'm inside of my parent but absolutely on top
                  </div>
                </div>
                I'm the parent
                <br /> You can modify my height
                <br /> and my child is always on top
                <br /> absolutely on top
                <br /> try removing this text
              </div>
            </div>

        【讨论】:

        • 如果 hack 类元素中有第二个子元素,高度为 300px,父类元素的兄弟元素高度为 150px。我们仍然看不到父类的新兄弟元素
        【解决方案8】:

        我遇到了类似的问题。 为了解决这个问题(而不是使用正文、文档或窗口来计算 iframe 的高度),我创建了一个包含整个页面内容的 div(例如,一个 id="page" 的 div),然后我使用了它的高度。

        【讨论】:

          【解决方案9】:

          我想出了另一个解决方案,我不喜欢但完成了工作。

          基本上以不可见的方式复制子元素。

          <div id="parent">
              <div class="width-calc">
                  <div class="child1"></div>
                  <div class="child2"></div>
              </div>
          
              <div class="child1"></div>
              <div class="child2"></div>
          </div>
          

          CSS:

          .width-calc {
              height: 0;
              overflow: hidden;
          }
          

          如果这些子元素包含很少的标记,那么影响就会很小。

          【讨论】:

          • 这会给搜索引擎排名带来一些问题
          【解决方案10】:

          “要么使用固定高度,要么需要 JS。”

          这里是 JS 示例:

          ---------- jQuery JS 示例---------

              function findEnvelopSizeOfAbsolutelyPositionedChildren(containerSelector){
                  var maxX = $(containerSelector).width(), maxY = $(containerSelector).height();
          
                  $(containerSelector).children().each(function (i){
                      if (maxX < parseInt($(this).css('left')) + $(this).width()){
                          maxX = parseInt($(this).css('left')) + $(this).width();
                      }
                      if (maxY < parseInt($(this).css('top')) + $(this).height()){
                          maxY = parseInt($(this).css('top')) + $(this).height();
                      }
                  });
                  return {
                      'width': maxX,
                      'height': maxY
                  }
              }
          
              var specBodySize = findEnvelopSizeOfAbsolutelyPositionedSubDivs("#SpecBody");
              $("#SpecBody").width(specBodySize.width);
              $("#SpecBody").height(specBodySize.height);
          

          【讨论】:

          • 这个答案可以从建议的解决方案的更好解释和方向中受益。
          【解决方案11】:

          现在有更好的方法来做到这一点。您可以使用底部属性。

              .my-element {
                position: absolute;
                bottom: 30px;
              }
          

          【讨论】:

          • 这只有在你知道父母的最终高度时才有效,而你不知道
          【解决方案12】:

          这与@ChrisC 的建议非常相似。它不是使用绝对定位元素,而是使用相对元素。也许对你有用

          <div class="container">
            <div class="my-child"></div>
          </div>
          

          你的css是这样的:

          .container{
              background-color: red;
              position: relative;
              border: 1px solid black;
              width: 100%;
          }
          
          .my-child{
              position: relative;
              top: 0;
              left: 100%;
              height: 100px;
              width: 100px;
              margin-left: -100px;
              background-color: blue;
          }
          

          https://jsfiddle.net/royriojas/dndjwa6t/

          【讨论】:

            【解决方案13】:

            同时考虑下一种方法:

            CSS:

            .parent {
              height: 100%;
            }
            .parent:after {
              content: '';
              display: block;
            }
            

            此外,由于您正在尝试重新定位 div,请考虑 css 网格

            【讨论】:

              【解决方案14】:

              绝对视图将自己定位在最近的非静态定位的祖先 (position: static) 上,因此如果您想要一个绝对视图定位在给定的父级上,请将父级 position 设置为 relative 并将子级设置为position 到 absolute

              【讨论】:

                【解决方案15】:

                试试这个,它对我有用

                .child {
                    width: 100%;
                    position: absolute;
                    top: 0px;
                    bottom: 0px;
                    z-index: 1;
                }
                

                它将子高度设置为父高度

                【讨论】:

                • 很好的解决方案!
                • @AlexanderCherednichenko 不是真的,它没有抓住问题的重点。
                猜你喜欢
                • 1970-01-01
                • 2014-08-23
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2023-03-22
                • 2010-11-16
                • 2012-01-01
                相关资源
                最近更新 更多