2013-09-22 23 views
8

Sto costruendo un designer di temi HTML/javascript per un CMS. Gli elementi sono posizionati in modo assoluto e possono essere spostati/ridimensionati tramite il mouse e/o contengono testo modificabile la cui altezza può essere determinata dal numero di linee. Tuttavia sto correndo nel problema in cui l'altezza di un elemento genitore non si espande per includere i suoi bambini posizionati in modo assoluto.Estendi l'altezza per includere i bambini posizionati in modo assoluto

codice minimo (anche su JSFiddle here):

<style> 
    div.layer { position: absolute } 
    div.layer1 { width: 400px; border: 1px solid #ccc } 
    div.layer2 { top: 15px; left: 100px; width: 100px; border: 1px solid blue } 
</style> 
<div class="layer layer1">container should expand to the bottom of the child. 
    <div class="layer layer2" contentEditable>Child with<br/>editable text.</div> 
</div> 

Una soluzione CSS-only è ideale e io non sono preoccupato per i browser più vecchi. Ma sono soprattutto alla ricerca di un modo per evitare che JavaScript venga eseguito su ogni pagina utilizzando un tema creato per impostarne l'altezza (poiché le pagine con lo stesso tema possono avere quantità di testo diverse).

Ci sono già alcune domande simili ma le risposte accettate (ad esempio, non utilizzare il posizionamento assoluto) non funzioneranno nel mio caso. A meno che non ci sia un modo per avere più livelli di elementi trascinabili/ridimensionabili senza che questi siano posizionati: assoluto.

+1

non so, ma non credo che può essere fatto con puro CSS. –

risposta

17

ho trovato una soluzione pura-CSS! In sintesi:

  1. Imposta gli elementi figli in posizione: relativo anziché assoluto.
  2. Imposta il loro margine-destra come larghezza negativa, per dare loro zero larghezza effettiva e renderli mobili: a sinistra per tenerli tutti sulla stessa riga. Questo fa sì che tutti abbiano origine 0, 0.
  3. Quindi possiamo impostare le loro proprietà left e margin-top per posizionarle assolutamente all'interno dei loro genitori. Si noti che margin-top è richiesto invece di top perché top non sposterà verso il basso la parte inferiore dell'elemento genitore.

JSFiddle here o codice qui sotto:

<style> 
    div.layer { position: relative; float: left; } 
    div.layer1 { width: 400px; border: 1px solid black } 
    div.layer2 { margin-top: 20px; left: 100px; width: 100px; margin-right: -100px; border: 1px solid blue } 
    div.layer3 { margin-top: 30px; left: 170px; width: 100px; margin-right: -100px; border: 1px solid red } 
    div.layer4 { margin-top: 30px; left: 20px; width: 60px; margin-right: -60px; border: 1px solid green } 
</style> 
<div class="layer layer1" style="position: relative; display: block; width: 400px; border: 1px solid black;"> 
    Container 
    <div class="layer layer2" contentEditable>Edit me</div> 
    <div class="layer layer3"> 
     <div class="layer layer4" contentEditable>Edit me</div> 
    </div> 
</div> 
+2

Questo è davvero brillante. Complimenti. +2 MySpace kudos per te (O +1 punti SO). – indextwo

4

elementi posizionati assoluti vengono rimossi dal flusso, quindi ignorato da altri elementi

l'unico modo che avete è di impostare la posizione bambino position: relative, in questo modo è possibile per spostarla utilizzando destra, a sinistra, sopra e sotto e cambiarne anche di visualizzazione principale per display: inline-block

+1

Grazie per l'idea, ma sfortunatamente questo non funziona quando ci sono più bambini. La posizione del secondo bambino è compensata dal primo, che è il comportamento previsto della posizione: relativo. – Dwayne

1

Se si desidera tenere i bambini posizionati in modo assoluto, si può utilizzare il seguente script per ridimensionare il contenitore: http://jsfiddle.net/6csrV/7/

var layer1 = document.getElementsByClassName('layer1'), 
    i = 0, len = layer1.length, childHeight; 
for(; i < len; i++) { 
    childHeight = layer1[i].getElementsByClassName('layer')[0].clientHeight; 
    layer1[i].style.height = childHeight + 'px'; 
} 
document.addEventListener('keyup', function(e) { 
    if(e.target.className.indexOf('layer2') !== false) { 
     e.target.parentNode.style.height = e.target.clientHeight + 'px'; 
    } 
}); 
+0

Userò una soluzione simile a questa se non trovo nulla di meglio. Ma diventa più complesso quando ci sono dozzine di elementi annidati in vari modi. Quello e non mi piace correre javascript sul caricamento della pagina per risolvere il layout. – Dwayne

Problemi correlati