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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12070759/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 02:25:19  来源:igfitidea点击:

Make absolute positioned div expand parent div height

htmlcsspositionmaster-pagesparent-child

提问by

As you can see in the CSS below, I want child2to position itself before child1. This is because the site I'm currently developing should also work on mobile devices, on which the child2should be at the bottom, as it contains the navigation which I want below the content on the mobile devices. - Why not 2 masterpages? This is the only 2 divswhich are repositioned in the entire HTML, so 2 masterpages for this minor change is an overkill.

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

HTML:

HTML:

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

CSS:

CSS:

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

child2has dynamic height, as different subsites could have more or less navigation items.

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

I know that absolute positioned elements are removed from the flow, thus ignored by other elements.
I tried setting overflow:hidden;on the parent div, but that didn't help, neither does the clearfix.

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

My last resort will be JavaScript to reposition the two divsaccordingly, but for now I'll try and see if there exist a non-JavaScript way of doing this.

我最后的手段是 JavaScript 来相应地重新定位这两个divs,但现在我将尝试看看是否存在非 JavaScript 的方式来做到这一点。

采纳答案by feeela

You answered the question by yourself: "I know that absolute positioned elements are removed from the flow, thus ignored by other elements." So you can't set the parents height according to an absolutely positioned element.

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

You either use fixed heights or you need to involve JS.

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

回答by lex82

Although stretching to elements with position: absoluteis not possible, there are often solutions where you can avoid the absolute positioning while obtaining the same effect. Look at this fiddle that solves the problem in your particular case http://jsfiddle.net/gS9q7/

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

The trick is to reverse element order by floating both elements, the first to the right, the second to the left, so the second appears first.

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

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

Finally, add a clearfix to the parent and you're done (see the fiddlefor the complete solution).

最后,向父级添加一个 clearfix 就完成了(请参阅fiddle以获取完整的解决方案)。

Generally, as long as the element with absolute position is positioned at the top of the parent element, chances are good that you find a workaround by floating the element.

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

回答by ChrisC

Feeelais rightbut you can get a parent divcontracting/expanding to a child element if you reverse your divpositioning like this:

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

This should work for you.

这应该对你有用。

回答by MMB

There is a quite simple way to solve this.

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

You just have to duplicate the content of child1 and child2 in relative divs with display:none in parent div. Say child1_1 and child2_2. Put child2_2 on top and child1_1 at the bottom.

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

When your jquery (or whatever) calls the absolute div, just set the according relative div (child1_1 or child2_2) with display:block AND visibility:hidden. The relative child will still be invisible but will make parent's div higher.

当您的 jquery(或其他)调用绝对 div 时,只需设置相应的相对 div(child1_1 或 child2_2)显示:块和可见性:隐藏。相对孩子仍然不可见,但会使父母的 div 更高。

回答by AndrewL64

With pure JavaScript, you just need to retrieve the height of your static positionchild element .child1using the getComputedStyle()method then set that retrieve value as the padding-topfor that same child using the HTMLElement.styleproperty.

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



Check and run the following Code Snippetfor a practical example of what I described above:

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

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

回答by Hunter Nelson

This question was asked in 2012 before flexbox. The correct way to solve this problem using modern CSS is with a media query and a flex column reversal for mobile devices. No absolute positioning is needed.

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

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

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

HTML:

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:

CSS:

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

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

回答by Juliano

I had a similar problem. To solve this (instead of calculate the iframe's height using the body, document or window) I created a div that wraps the whole page content (a div with an id="page" for example) and then I used its height.

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

回答by Nikolay

"You either use fixed heights or you need to involve JS."

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

Here is the JS example:

这是JS示例:

---------- jQuery JS example--------------------

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

回答by btx9000

I came up with another solution, which I don't love but gets the job done.

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

Basically duplicate the child elements in such a way that the duplicates are not visible.

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

<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:

CSS:

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

If those child elements contain little markup, then the impact will be small.

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

回答by bernatfortet

There's a very simple hack that fixes this issue

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

Here's a codesandbox that illustrates the solution: https://codesandbox.io/s/00w06z1n5l

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

HTML

HTML

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

CSS

CSS

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

you can play with the positioning of the hack div to affect where the child positions itself.

您可以调整 hack div 的位置来影响孩子自己的位置。

Here's a snippet:

这是一个片段:

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>