Сделать абсолютное позиционирование div, увеличить родительский div div

204

Как вы можете видеть в 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.

Миха Виденманн
источник
3
Я не уверен на 100%, но я думаю, что вам, вероятно, придется пойти на решение JS, которое рассчитывает рост child2 и соответственно перемещает child1.
Билли Ров
2
Это можно сделать, установив положение родителя на относительное, а дочернее - на абсолютное.
fungusanthrax
1
Посмотрите этот обходной путь, может быть, это может помочь.
Az.Youness

Ответы:

153

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

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

feeela
источник
1
Я отмечаю это, поскольку это технически правильный путь, хотя я нашел другое решение моей проблемы, которое заключается в том, чтобы практически внедрить требуемый CSS на конкретные страницы, которые должны различаться (2 из 40 на данный момент).
16

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

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

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

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

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

lex82
источник
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 */
}

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

ChrisC
источник
9

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

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

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

MMB
источник
2
Это заставило меня задуматься в правильном направлении. В моем случае установка display: ни один в содержимом «Держатель размера» не делает div размером, но непрозрачность: 0 корректно определяет размер div и не требует никаких дополнительных jquery.
edencorbin
Я сделал так, чтобы получить два дубликата div, первый - это видимый контент с абсолютной позицией, а второй - div с скрытой видимостью, в котором родительский div с правильной высотой все работает отлично = D
Diogo Garcia
4

В чистом 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>

AndrewL64
источник
3

Этот вопрос был задан в 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 bottom on mobile
    </p>
  </div>
</div>

CSS:

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

@media (max-width: 768px) {
  .parent {
    flex-direction: column-reverse;
  }
}
Хантер Нельсон
источник
2

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

Жулиано
источник
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;
}

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

btx9000
источник
4
Это может дать некоторые проблемы с ранжированием в
поисковиках
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

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

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

bernatfortet
источник
0

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

    .my-element {
      position: absolute;
      bottom: 30px;
    }
rlasch
источник
5
это будет работать, только если вы знаете конечную высоту родителя, а вы не
знаете
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 grid

Егор Бензик
источник
-2

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

Исаак Секаматте
источник
-4

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

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

Это установит дочернюю высоту к родительской высоте

Сарат Е
источник
отличное решение!
Александр Чередниченко
3
@AlexanderChednichenko Не совсем, он упускает суть вопроса.
wickywills