使绝对定位的div扩展父div的高度


204

如您在下面的CSS中所看到的,我想child2将自己定位在之前child1。这是因为我当前正在开发的网站也可以在移动设备上工作,该网站child2应该位于底部,因为它包含了我想要的导航,该导航位于移动设备上的内容下方。-为什么没有2个母版页?这是divs在整个HTML中重新定位的仅有2个,因此,对于这个较小的更改,只有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 具有动态高度,因为不同的子站点可能具有更多或更少的导航项。

我知道绝对定位元素已从流中删除,因此被其他元素忽略。
我尝试overflow:hidden;在父div上进行设置,但这没有帮助,也不起作用clearfix

我的最后一个选择是使用JavaScript重新定位两者divs,但是现在,我将尝试看看是否存在使用非JavaScript的方法。


3
我不确定100%,但是我认为您可能需要使用JS解决方案,该解决方案可以计算出child2的高度并相应地移动child1。
比利·护城河

2
这可以通过将父母的位置设置为相对位置,将孩子的位置设置为绝对位置来完成。
fungusanthrax

1
请参阅此解决方法,它可能会有所帮助。
Az.Youness

Answers:


151

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

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


1
我将其标记为技术上正确的方法,尽管我找到了解决我问题的另一种方法,实际上是将所需的CSS嵌套在必须区分的特定页面上(目前40分之2)。

16

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

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

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

最后,向父级添加一个clearfix,您就完成了(请参见小提琴完整的解决方案)。

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


10

Feeela是正确的,但是div如果您div像这样反转位置,则可以使父元素收缩/扩展为子元素:

.parent{
    postion: 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 */
}

这应该为您工作。


9

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

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

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


2
这使我思考正确的方向。在我的情况下,设置显示:“ sizeholder”内容中的任何内容都不会使div产生大小,但是不透明性:0,可以正确调整div的大小,并且不需要任何其他的jquery。
edencorbin '16

我的方法是获得两个重复的div,第一个是位置绝对的可见内容,第二个是隐藏可见性的div,使父div保持正确的高度都可以正常工作= D
Diogo Garcia

4

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


检查并运行以下代码片段,以获取上述内容的实际示例:

/* 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>


2

我有一个类似的问题。为了解决这个问题(而不是使用主体,文档或窗口来计算iframe的高度),我创建了一个div,该div包裹了整个页面的内容(例如,一个具有id =“ page”的div),然后使用其高度。


2

在flexbox之前的2012年,曾问过这个问题。使用现代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 bottom on mobile
    </p>
  </div>
</div>

CSS:

.parent {
  display: flex;
  flex-direction: column;
}

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

1

我想出了另一种解决方案,虽然我不喜欢但可以完成工作。

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

<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;
}

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


4
这可能会给搜索引擎排名带来一些问题
mschadegg '16

1

“您要么使用固定的高度,要么需要使用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);

该答案可能会从提出的解决方案的更好解释和方向中受益。
DaniDev

1

有一个非常简单的技巧可以解决此问题

这是一个说明解决方案的codeandbox: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的位置来影响孩子自己的位置。

这是一个片段:

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>


0

现在有一种更好的方法。您可以使用bottom属性。

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

5
仅在您知道父母的最终身高而不知道的情况下,此方法才有效
machineaddict 2015年

0

这与@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/


0

还考虑下一种方法:

CSS:

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

另外,由于您尝试重新定位div,因此请考虑使用CSS网格


-2

绝对视图将自身相对于未静态定位的最接近的祖先position: static,因此,如果您希望绝对视图相对于给定的父代定位,请将父代设置positionrelative,子代设置positionabsolute


-4

试试这个,对我有用

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

它将孩子的身高设置为父母的身高


很好的解决方案!
亚历山大·切雷迪尼琴科

3
@AlexanderCherednichenko并非如此,它错过了问题的重点。
wickywills
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.