2013-09-22 22 views
8

Buduję projektanta motywów HTML/JavaScript dla CMS. Elementy są umieszczone absolutnie i mogą być przesuwane/zmieniane za pomocą myszy i/lub zawierają edytowalny tekst, którego wysokość może być określona przez liczbę linii. Jednak napotykam problem, w którym wysokość elementu rodzica nie rozszerza się, aby uwzględnić jego absolutnie pozycjonowane elementy potomne.Zwiększenie wysokości w celu uwzględnienia absolutnie rozmieszczonych dzieci

Minimal kod (także na 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> 

CSS-jedynym rozwiązaniem jest idealny i nie jestem zaniepokojony starszych przeglądarek. Ale głównie szukam sposobu, aby zapobiec uruchamianiu javascript na każdej stronie przy użyciu utworzonego motywu, aby ustawić ich wysokość (ponieważ strony o tym samym motywie mogą mieć różne ilości tekstu).

Istnieje już kilka podobnych pytań, ale ich zaakceptowane odpowiedzi (np. Nie używają pozycjonowania bezwzględnego) nie będą działać w moim przypadku. Chyba że istnieje sposób na umieszczenie wielu warstw elementów, które można przeciągnąć/zmienić, bez pozycji: absolutna.

+1

Nie wiem, ale nie sądzę, można to zrobić z czystym CSS. –

Odpowiedz

17

znalazłem rozwiązanie czystego CSS! Podsumowując:

  1. Ustaw elementy podrzędne na położenie: względne zamiast bezwzględne.
  2. Ustaw ich margines-prawo na szerokość ujemną, aby uzyskać zerową skuteczną szerokość i spraw, aby były unoszone: po lewej, aby zachować je wszystkie na tej samej linii. To sprawia, że ​​wszystkie z nich mają początek 0, 0.
  3. Następnie możemy ustawić ich właściwości left i margin-top, aby umieścić je absolutnie w obrębie swoich rodziców. Zauważ, że margin-top jest wymagany zamiast top, ponieważ top nie będzie wciskał dolnej części elementu nadrzędnego.

JSFiddle here lub kod poniżej:

<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

To jest naprawdę genialne. Sława. +2 MySpace dla Ciebie (lub +1 punktów SO). – indextwo

4

bezwzględne elementy umieszczone są usuwane ze strumienia, zatem ignorowane przez innych elementów

jedynym sposobem masz jest, aby ustawić pozycję dziecka do position: relative, w ten sposób możliwe jest przenieść go za pomocą prawo, lewo, góra i dół a także zmienić wyświetlanie dominującej display: inline-block

+1

Dzięki za pomysł, ale niestety to się nie udaje, gdy jest wiele dzieci. Pozycja drugiego dziecka jest przesunięta względem pierwszej, czyli zamierzonego zachowania pozycji: względna. – Dwayne

1

Jeśli chcesz zachować dzieci absolutnie pozycjonowane, można kliknąć na poniższy skrypt do zmiany rozmiaru pojemnika: 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

Będę używał rozwiązania podobnego do tego, jeśli nie znajdę nic lepszego. Ale staje się bardziej skomplikowany, gdy na różne sposoby znajdują się dziesiątki elementów. To i nie podoba mi się uruchamianie javascript na ładowanie strony, aby naprawić układ. – Dwayne