Fai div assoluto posizionato div espandere l'altezza div padre


204

Come puoi vedere nel CSS qui sotto, voglio child2posizionarmi prima child1. Questo perché il sito che sto attualmente sviluppando dovrebbe funzionare anche su dispositivi mobili, su cui child2dovrebbe trovarsi in fondo, in quanto contiene la navigazione che desidero sotto il contenuto sui dispositivi mobili. - Perché non 2 pagine master? Questo è l'unico 2 divsche viene riposizionato in tutto l'HTML, quindi 2 pagine master per questa modifica minore sono un eccesso.

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 ha un'altezza dinamica, poiché diversi siti secondari potrebbero avere più o meno elementi di navigazione.

So che gli elementi posizionati assoluti vengono rimossi dal flusso, quindi ignorati da altri elementi.
Ho provato a impostare overflow:hidden;il div genitore, ma questo non ha aiutato, né il clearfix.

La mia ultima risorsa sarà JavaScript per riposizionare i due di divsconseguenza, ma per ora proverò a vedere se esiste un modo non JavaScript per farlo.


3
Non sono sicuro al 100%, ma penso che probabilmente dovrai scegliere una soluzione JS che risolve l'altezza di child2 e sposta child1 di conseguenza.
Billy Moat,

2
Questo può essere fatto impostando la posizione del genitore su relativa e il figlio su assoluto.
fungusanthrax,

1
Vedi questa soluzione alternativa forse può essere d'aiuto.
Az.Youness,

Risposte:


153

Hai risposto alla domanda da solo: "So che gli elementi posizionati assoluti vengono rimossi dal flusso, quindi ignorati da altri elementi". Quindi non puoi impostare l'altezza dei genitori secondo un elemento assolutamente posizionato.

O usi altezze fisse o devi coinvolgere JS.


1
Sto contrassegnando questo come tecnicamente è il modo corretto, anche se ho trovato un'altra soluzione al mio problema, che è praticamente quella di annidare i CSS richiesti nelle pagine specifiche che devono differenziarsi (2 su 40 al momento).

16

Sebbene position: absolutenon sia possibile allungare gli elementi con , spesso ci sono soluzioni in cui è possibile evitare il posizionamento assoluto ottenendo lo stesso effetto. Guarda questo violino che risolve il problema nel tuo caso particolare http://jsfiddle.net/gS9q7/

Il trucco è invertire l'ordine degli elementi fluttuando entrambi gli elementi, il primo a destra, il secondo a sinistra, quindi il secondo appare per primo.

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

Infine, aggiungi un clearfix al genitore e il gioco è fatto (vedi il violino per la soluzione completa).

Generalmente, fintanto che l'elemento con posizione assoluta è posizionato nella parte superiore dell'elemento genitore, è probabile che trovi una soluzione alternativa facendo galleggiare l'elemento.


10

Feeela ha ragione, ma puoi ottenere un genitore che sidivcontrae / si espande in un elemento figlio se inverti ildivposizionamento in questo modo:

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

Questo dovrebbe funzionare per te.


9

C'è un modo abbastanza semplice per risolvere questo.

Devi solo duplicare il contenuto di child1 e child2 in div relativi con display: none in div parent. Pronuncia child1_1 e child2_2. Metti child2_2 in alto e child1_1 in basso.

Quando il tuo jquery (o qualunque altra cosa) chiami il div assoluto, basta impostare il div relativo (child1_1 o child2_2) con display: blocco E visibilità: nascosto. Il bambino relativo sarà comunque invisibile ma aumenterà il div dei genitori.


2
Questo mi ha fatto pensare nella giusta direzione. Nel mio display di impostazione del caso: nessuno nel contenuto "holder size" rende il div non di dimensioni, tuttavia l'opacità: 0, dimensiona il div correttamente e non richiede alcun jquery aggiuntivo.
edencorbin,

Il modo in cui ho fatto è stato quello di ottenere due div duplicati, il primo è il contenuto visibile con posizione assoluta e il secondo è un div con visibilità nascosta che mantiene il div parent con l'altezza corretta tutto funziona bene = D
Diogo Garcia

4

Con JavaScript puro, devi solo recuperare l'altezza static positiondell'elemento figlio .child1usando il metodo getComputedStyle () quindi impostare quel valore di recupero come padding-topper quello stesso figlio usando la proprietà HTMLElement.style .


Controlla ed esegui il seguente frammento di codice per un esempio pratico di ciò che ho descritto sopra:

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


3

Questa domanda è stata posta nel 2012 prima di flexbox. Il modo corretto di risolvere questo problema utilizzando i CSS moderni è con una query multimediale e un'inversione di colonna flessibile per dispositivi mobili. Non è necessario alcun posizionamento assoluto.

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

Ho avuto un problema simile. Per risolvere questo problema (invece di calcolare l'altezza dell'iframe usando il corpo, il documento o la finestra) ho creato un div che avvolge l'intero contenuto della pagina (un div con un id = "page" per esempio) e quindi ho usato la sua altezza.


1

Ho trovato un'altra soluzione, che non amo ma che fa il lavoro.

Fondamentalmente duplicare gli elementi figlio in modo tale che i duplicati non siano visibili.

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

Se quegli elementi figlio contengono un piccolo markup, l'impatto sarà piccolo.


4
Questo può dare alcuni problemi con il posizionamento nei motori di ricerca
mschadegg,

1

"O usi altezze fisse o devi coinvolgere JS."

Ecco l'esempio di JS:

---------- jQuery JS esempio --------------------

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

Questa risposta potrebbe beneficiare di una migliore spiegazione e direzione della soluzione proposta.
DaniDev,

1

C'è un trucco molto semplice che risolve questo problema

Ecco un codesandbox che illustra la soluzione: 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; }

puoi giocare con il posizionamento del div hack per influenzare la posizione del bambino.

Ecco uno 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>


0

C'è un modo migliore per farlo ora. È possibile utilizzare la proprietà in basso.

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

5
questo funzionerà solo se conosci l'altezza finale del genitore, cosa che non fai
machineaddict

0

Questo è molto simile a quanto suggerito da @ChrisC. Non utilizza un elemento posizionato in modo assoluto, ma uno relativo. Forse potrebbe funzionare per te

<div class="container">
  <div class="my-child"></div>
</div>

E i tuoi css in questo modo:

.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

Considera anche il prossimo approccio:

CSS:

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

Anche dal momento che stai cercando di riposizionare i div, considera la griglia CSS


-2

Le viste assolute si posizionano contro l'antenato più vicino che non è posizionato staticamente ( position: static), quindi se si desidera una vista assoluta posizionata su un determinato genitore, impostare il genitore positionsu relativee il figlio su positionsuabsolute


-4

Prova questo, ha funzionato per me

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

Imposta l'altezza del bambino all'altezza del genitore


ottima soluzione!
Alexander Cherednichenko,

3
@AlexanderCherednichenko Non proprio, manca il punto della domanda.
wickywills,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.