Зробіть абсолютний розміщений 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

Відповіді:


152

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

Ви або використовуєте фіксовану висоту, або потрібно залучати JS.


1
Я відзначаю це так, як це технічно є правильним способом, хоча я знайшов інше рішення моєї проблеми, яке полягає в тому, щоб практично вкласти потрібний css на конкретні сторінки, які мають відрізнятись (2 з 40 на даний момент).

16

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

Хитрість полягає в тому, щоб повернути порядок елементів плаваючи обома елементами, перший праворуч, другий ліворуч, тому другий з’являється першим.

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

Нарешті, додайте до батьківського чіткого виправлення, і ви закінчите (див. Загадку для повного рішення).

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


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

Існує досить простий спосіб вирішити це.

Вам просто потрібно дублювати вміст child1 та child2 у відносних дівах із відображенням: жоден у батьківському ділі. Скажіть, що дитина1_1 та дитина2_2. Покладіть child2_2 вгорі, а child1_1 внизу.

Коли ваш jquery (або що завгодно) викликає абсолютний div, просто встановіть відповідний div (child1_1 або child2_2) з показом: block AND видимість: приховано. Відносна дитина все ще буде непомітною, але зробить дівочі батьки вищими.


2
Це змусило мене думати в правильному напрямку. У моєму випадку відображення налаштувань: жоден вміст "власника розміру" не робить розмір div не розміром, проте непрозорість: 0, розмір діва правильно та не потребує додаткових jquery.
edencorbin

Те , як я зробив, щоб отримати два дублюючих діви перших з них є видимим зміст з позицією абсолютним і другий один є ДІВИМ з видимістю прихованої , який тримає батьківський DIV з правильною висотою все працює відмінно = D
Діий 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>


2

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


2

Це запитання було задано у 2012 році перед флексбоком. Правильний спосіб вирішити цю проблему за допомогою сучасного CSS - це медіа-запит та зворотний стовпець flex для мобільних пристроїв. Не потрібно абсолютного позиціонування.

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

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

ви можете пограти з позиціонуванням хак-діва, щоб вплинути на місце розташування дитини.

Ось фрагмент:

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

Є кращий спосіб зробити це зараз. Ви можете використовувати властивість нижньої частини.

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

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

Крім того, оскільки ви намагаєтесь розмістити divs, розгляньте css grid


-2

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


-4

Спробуйте це, для мене це працювало

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

Він встановить зріст дитини на батьківський зріст


чудове рішення!
Олександр Чередніченко

3
@AlexanderCherednichenko Насправді, це не вистачає суті питання.
wickywills
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.