Сделать абсолютное положение div expand parent div height

Как вы можете видеть в CSS ниже, я хочу, чтобы child2 позиционировал себя перед child1. Это потому, что сайт, который я сейчас разрабатываю, должен также работать на мобильных устройствах, где child2 должен быть внизу, так как он содержит навигацию, которую я хочу, под контентом на мобильных устройствах. - Почему бы не 2 шедевры? Это единственные 2 divs, которые переставлены во всем HTML, так что 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.

Ответ 1

Вы сами ответили на вопрос: "Я знаю, что абсолютные позиционируемые элементы удаляются из потока, игнорируются другими элементами". Таким образом, вы не можете установить высоту родителей в соответствии с абсолютно позиционированным элементом.

Вы либо используете фиксированные высоты, либо вам нужно включить JS.

Ответ 2

Хотя растягивание на элементы с position: absolute невозможно, часто возникают решения, в которых вы можете избежать абсолютного позиционирования при получении того же эффекта. Посмотрите на эту скрипку, которая решает проблему в вашем конкретном случае http://jsfiddle.net/gS9q7/

Трюк состоит в том, чтобы отменить порядок элементов, перемещая оба элемента, первый вправо, второй влево, поэтому сначала появляется вторая.

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

Наконец, добавьте clearfix родительскому элементу, и все готово (см. fiddle для полного решения).

В общем случае, пока элемент с абсолютным положением расположен в верхней части родительского элемента, вероятность того, что вы обнаружите обходной путь путем плавания элемента, имеет хорошие шансы.

Ответ 3

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

Это должно работать для вас.

Ответ 4

Существует довольно простой способ решить эту проблему.

Вам просто нужно дублировать содержимое child1 и child2 в относительных divs с отображением: none в родительском div. Скажем child1_1 и child2_2. Поместите child2_2 сверху и child1_1 внизу.

Когда ваш jquery (или что-то другое) вызывает абсолютный div, просто установите соответствующий относительный div (child1_1 или child2_2) с отображением: block AND visibility: hidden. Относительный ребенок все равно будет невидим, но сделает родительский div выше.

Ответ 5

У меня была аналогичная проблема. Чтобы решить эту проблему (вместо вычисления высоты iframe с помощью тела, документа или окна), я создал div, который обертывает весь контент страницы (например, div с id = "страница" ), а затем я использовал его высоту.

Ответ 6

Там очень простой взлом, который исправляет эту проблему

Вот коды и окно, иллюстрирующее решение: 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>

Ответ 7

В чистом JavaScript вам просто нужно получить высоту вашего дочернего элемента static position .child1 используя метод getComputedStyle(), а затем установить это извлечение значения в качестве 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>

Ответ 8

Я придумал другое решение, которое мне не нравится, но выполняет свою работу.

В основном дублировать дочерние элементы таким образом, чтобы дубликаты не были видны.

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

Если эти дочерние элементы содержат небольшую разметку, тогда воздействие будет небольшим.

Ответ 9

"Вы либо используете фиксированную высоту, либо вам нужно задействовать JS".

Вот пример JS:

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

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

Ответ 10

Это очень похоже на то, что предложил @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/

Ответ 11

Теперь есть лучший способ сделать это. Вы можете использовать нижнее свойство.

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

Ответ 12

Также рассмотрим следующий подход:

CSS:

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

Кроме того, так как вы пытаетесь изменить положение div, рассмотрите css grid

Ответ 13

Абсолютные мнения позиционируют себя от ближайшего предка, не статический позиционируются (position: static), поэтому если вы хотите абсолютный вид, расположенный против данного родителя, установить родительскую position по relative и ребенку position в absolute

Ответ 14

Попробуй, это сработало для меня

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

Он установит высоту ребенка на родительскую высоту