CSS - Rozwiń pływającą wysokość DIV dziecka do wysokości rodzica

451

Mam strukturę strony jako:

<div class="parent">
    <div class="child-left floatLeft">
    </div>

    <div class="child-right floatLeft">
    </div>
</div>

Teraz child-leftDIV będzie zawierał więcej treści, więc parentwysokość DIV wzrasta zgodnie z DIV dziecka.

Problem w tym, że child-rightwysokość się nie zwiększa. Jak mogę wyrównać jego wysokość do jego rodzica?

Veera
źródło
2
Prosty. Łatwy. Kolumny o równej wysokości z Flexbox .
Michael Benjamin

Odpowiedzi:

459

Dla parentelementu dodaj następujące właściwości:

.parent {
    overflow: hidden;
    position: relative;
    width: 100%;
}

następnie dla .child-righttych:

.child-right {
    background:green;
    height: 100%;
    width: 50%;
    position: absolute;
    right: 0;
    top: 0;
}

Znajdź bardziej szczegółowe wyniki z przykładami CSS tutaj i więcej informacji na temat kolumn o równej wysokości tutaj .

Sotiris
źródło
14
Twój CSS powoduje niezdefiniowane zachowanie - wzrost rodzica zależy od wzrostu dziecka, ale dzieci mają procentową wysokość zdefiniowaną w odniesieniu do rodzica: jest to nieprawidłowe i prawdopodobnie nie będzie działać w przeglądarce.
Eamon Nerbonne
1
Widzę, że nie przestawiasz wszystkiego - więc jest to zdefiniowane kosztem nie skalowania, jeśli kiedykolwiek prawa kolumna rośnie dłużej niż lewa (co w rzeczywistości nie jest w przypadku pytania PO).
Eamon Nerbonne
4
Tak, musisz dodać to: padding-bottom: 32768px; margines na dole: -32768px; do dzieci.
Michael
3
Działa to tak długo, jak gwarantuje się, że prawa kolumna ma mniej treści niż lewa, w przeciwnym razie zostanie przycięta. Zredagowałem również odpowiedź, aby pominąć bezużyteczne deklaracje.
Christoph
3
@MatthewBlackford: jest to „hack”, ponieważ zapobiega zawaleniu się marży. Można zapobiec zwijaniu się marginesów na inne sposoby, na przykład za pomocą przezroczystej ramki o wielkości 1 piksela, ale w istocie, ale ważne jest, aby uniknąć zwinięcia marginesu. Nie użyłbym tego rozwiązania, chyba że w ostateczności, ponieważ powoduje on dziwne błędy układu i nieoczekiwane kadrowanie (lub nakładanie treści), gdy twoje założenia okazują się błędne. Krótko mówiąc: nie chcesz tego robić, chyba że naprawdę musisz.
Eamon Nerbonne
206

Wspólne rozwiązanie tego problemu wykorzystuje pozycjonowanie bezwzględne lub przycięte zmiennoprzecinkowe, ale są one trudne, ponieważ wymagają obszernego dostrajania, jeśli liczba kolumn zmienia się pod względem liczby i rozmiaru, i że musisz upewnić się, że kolumna „główna” jest zawsze najdłuższa. Zamiast tego sugeruję użycie jednego z trzech bardziej niezawodnych rozwiązań:

  1. display: flex: zdecydowanie najprostsze i najlepsze rozwiązanie oraz bardzo elastyczne - ale nieobsługiwane przez IE9 i starsze.
  2. tablelub display: table: bardzo prosty, bardzo kompatybilny (prawie każda przeglądarka kiedykolwiek), dość elastyczny.
  3. display: inline-block; width:50% z hackowaniem marginesów ujemnych: dość proste, ale obramowanie dolnej kolumny jest trochę trudne.

1. display:flex

Jest to naprawdę proste i łatwe do dostosowania do bardziej złożonych lub bardziej szczegółowych układów - ale Flexbox jest obsługiwany tylko przez IE10 lub nowszą wersję (oprócz innych nowoczesnych przeglądarek).

Przykład: http://output.jsbin.com/hetunujuma/1

Odpowiedni HTML:

<div class="parent"><div>column 1</div><div>column 2</div></div>

Odpowiednie css:

.parent { display: -ms-flex; display: -webkit-flex; display: flex; }
.parent>div { flex:1; }

Flexbox obsługuje wiele innych opcji, ale wystarczy mieć dowolną liczbę kolumn, wystarczy powyższe!

2. <table>lubdisplay: table

Prostym i niezwykle kompatybilnym sposobem na wykonanie tego jest table- polecam najpierw spróbować, jeśli potrzebujesz obsługi starego IE . Masz do czynienia z kolumnami; divs + float po prostu nie jest najlepszym sposobem na zrobienie tego (nie wspominając o tym, że wiele poziomów zagnieżdżonych div tylko po to, by włamać się do ograniczeń css, nie jest bardziej „semantyczne” niż zwykła tabela). Jeśli nie chcesz używać tego tableelementu, rozważ cssdisplay: table (nieobsługiwany przez IE7 i starsze).

Przykład: http://jsfiddle.net/emn13/7FFp3/

Odpowiedni HTML: (ale<table>zamiast tegorozważ użycie zwykłego)

<div class="parent"><div>column 1</div><div>column 2</div></div>

Odpowiednie css:

.parent { display: table; }
.parent > div {display: table-cell; width:50%; }
/*omit width:50% for auto-scaled column widths*/

To podejście jest znacznie bardziej niezawodne niż w overflow:hiddenprzypadku pływaków. Możesz dodać prawie dowolną liczbę kolumn; możesz je skalować automatycznie, jeśli chcesz; i zachowujesz zgodność ze starymi przeglądarkami. W przeciwieństwie do rozwiązania typu float, nie musisz wcześniej wiedzieć, która kolumna jest najdłuższa; wysokość dobrze się skaluje.

KISS: nie używaj haków pływakowych, chyba że potrzebujesz. Jeśli IE7 stanowi problem, nadal wybieram zwykłą tabelę z kolumnami semantycznymi zamiast trudnego w utrzymaniu, mniej elastycznego rozwiązania trick-CSS każdego dnia.

Nawiasem mówiąc, jeśli potrzebujesz, aby układ był responsywny (np. Brak kolumn na małych telefonach komórkowych), możesz użyć @mediazapytania, aby powrócić do zwykłego układu bloków dla małych szerokości ekranu - działa to niezależnie od tego, czy używasz, <table>czy innego display: tableelementu.

3. display:inline blockz ujemnym włamaniem do marginesu.

Inną alternatywą jest użycie display:inline block.

Przykład: http://jsbin.com/ovuqes/2/edit

Odpowiedni html: (brak spacji międzydivznacznikami jest znaczący!)

<div class="parent"><div><div>column 1</div></div><div><div>column 2</div></div></div>

Odpowiednie css:

.parent { 
    position: relative; width: 100%; white-space: nowrap; overflow: hidden; 
}

.parent>div { 
    display:inline-block; width:50%; white-space:normal; vertical-align:top; 
}

.parent>div>div {
    padding-bottom: 32768px; margin-bottom: -32768px; 
}

Jest to nieco trudne, a ujemny margines oznacza, że ​​„prawdziwy” dół kolumn jest zasłonięty. To z kolei oznacza, że ​​nie możesz ustawić niczego względem dołu tych kolumn, ponieważ jest to odcięte overflow: hidden. Pamiętaj, że oprócz bloków wbudowanych możesz osiągnąć podobny efekt za pomocą pływaków.


TL; DR : użyj Flexboksa, jeśli możesz zignorować IE9 i starsze; w przeciwnym razie wypróbuj tabelę (css). Jeśli żadna z tych opcji nie jest dla ciebie odpowiednia, występują hacki o ujemnym marginesie, ale mogą powodować dziwne problemy z wyświetlaniem, których łatwo przeoczyć podczas programowania, i istnieją ograniczenia dotyczące układu, o których musisz pamiętać.

Eamon Nerbonne
źródło
1
Dobry, ale warto zauważyć, że nie można używać marginesów między tymi komórkami (a wypełnianie nie pomoże, jeśli chcesz je stylizować).
Wordpressor,
3
border-spacing:10px;na stole wprowadzi odstępy podobne do marginesów. Alternatywnie możesz dodać dodatkowe (puste) kolumny, w których chcesz uzyskać dodatkowe miejsce. Możesz także dodać dopełnienie w komórkach tabeli; to wypełnienie zostanie uwzględnione w tle, więc może nie być to, czego chcesz. Ale masz rację, że nie jest tak elastyczny jak zwykły margines. I nie możesz ustawić niczego względem kolumn, co może stanowić problem.
Eamon Nerbonne,
1
Czy to lepiej układ bez tabel, czy nie?
dynamiczny
3
Muszę powiedzieć: Zgadzam się z tobą, że w tym przypadku zwykły stół jest więcej niż wystarczający. Problem polega na tym, że istnieje wspólny widok ignorowania każdego układu z tabelą
dynamiczny
3
Problem z tabelą polega na tym, że po zmianie rozmiaru ekranu na mniejszą szerokość (projektowanie responsywne) komórki tabeli ulegają zgnieceniu zamiast układania jednego nad drugim. Druga metoda z padding-bottom: 32768px; margines na dole: -32768px; jest całkiem niesamowite i robi prawie dokładnie to, czego potrzebowałem ... dzięki za to ... problem z dolną krawędzią jest jednak problemem ...
Serj Sagan
23

Dla rodzica:

display: flex;

Dla dzieci:

align-items: stretch;

Powinieneś dodać kilka prefiksów, sprawdź caniuse.

Aiphee
źródło
2
Nie poleciłbym. IE9 to wciąż coś.
Dziękuję za Twoją odpowiedź; to dobrze działa! „Powinieneś dodać kilka prefiksów, sprawdź caniuse.” co rozumiesz przez tę linię? Czy możesz dodać trochę więcej informacji dla początkujących?
Md Sifatul Islam,
@MdSifatulIslam Idź tutaj: caniuse.com/#feat=flexbox Możesz sprawdzić, czy niektóre przeglądarki, które potrzebujesz obsługiwać, wymagają prefiksu funkcji.
Aiphee,
18

Znalazłem wiele odpowiedzi, ale prawdopodobnie najlepszym rozwiązaniem dla mnie jest

.parent { 
  overflow: hidden; 
}
.parent .floatLeft {
  # your other styles
  float: left;
  margin-bottom: -99999px;
  padding-bottom: 99999px;
}

Możesz sprawdzić inne rozwiązania tutaj http://css-tricks.com/fluid-width-equal-height-columns/

Dobromir Minchev
źródło
Nie mam pojęcia, dlaczego to działa, ale rozwiązuje mój problem jak urok. Dziękuję
Połącz
Dla mnie też działa. Mimo że nie jest to czysty sposób. Dzięki!
Mark Anthony Uy
18
paskudny jak diabli. Nie polecam tego do zastosowań produkcyjnych
FedericoCapaldo
to jest niesamowite haha. Nie sądziłem, że to rzeczywiście zadziała
Tom McDonough,
11

Proszę ustawić div div, aby overflow: hidden
w divach potomnych można było ustawić dużą ilość dla padding-bottom. na przykład
padding-bottom: 5000px
wtedy margin-bottom: -5000px
i wtedy wszystkie div div dziecka będą wysokością rodzica.
Oczywiście to nie zadziała, jeśli próbujesz wstawić treść do nadrzędnego div (poza innymi div div)

.parent{
    border: 1px solid black;
    overflow: hidden;
    height: auto;
}
.child{
    float: left;
    padding-bottom: 1500px;
    margin-bottom: -1500px;
}
.child1{
    background: red;
    padding-right: 10px;    
}
.child2{
    background: green;
    padding-left: 10px;
}
<div class="parent">
    <div class="child1 child">
        One line text in child1
    </div>
    <div class="child2 child">
        Three line text in child2<br />
        Three line text in child2<br />
        Three line text in child2
    </div>
</div>

Przykład: http://jsfiddle.net/Tareqdhk/DAFEC/

Tareq
źródło
wydaje się trochę brudny, ale działał dla mnie - jedyne rozwiązanie na to pytanie. Próbowałem tego za pomocą paska startowego Twittera.
cukabeka
8

Czy rodzic ma wzrost? Jeśli tak ustawisz wysokość rodziców.

div.parent { height: 300px };

Następnie możesz sprawić, by dziecko rozciągało się na pełną wysokość w ten sposób.

div.child-right { height: 100% };

EDYTOWAĆ

Oto, jak zrobiłbyś to za pomocą JavaScript.

Olical
źródło
rodzic nie ma stałej wysokości. Rozszerza się zgodnie z wysokością pozostawioną przez dziecko.
Veera
Ach, tak samo myślałem, wtedy będziesz potrzebować trochę JavaScript, dodam go za sekundę.
Olical
@Olical JSFiddle link jest uszkodzony. Usuń go lub zaktualizuj odpowiedź. Dzięki!
itsmysterybox
1
Link do js daje teraz 404
Chanoch
5

Wyświetlanie tabeli CSS jest idealne do tego:

.parent {
  display: table;
  width: 100%;
}
.parent > div {
  display: table-cell;
}
.child-left {
  background: powderblue;
}
.child-right {
  background: papayawhip;
}
<div class="parent">
  <div class="child-left">Short</div>
  <div class="child-right">Tall<br>Tall</div>
</div>

Oryginalna odpowiedź (zakładając, że dowolna kolumna może być wyższa):

Próbujesz uzależnić wzrost rodzica od wzrostu dziecka, a wzrost dziecka od wzrostu rodzica. Nie da się obliczyć. Sztuczne kolumny CSS to najlepsze rozwiązanie. Jest na to więcej niż jeden sposób. Wolałbym nie używać JavaScript.

Salman A.
źródło
Słuszna uwaga. Co powiesz na to, czy wzrost dziecka zależy od wysokości najwyższego rodzeństwa (czy to zależy od wzrostu rodzica, czy nie), a nie od rodzica? Myślę, że nie można tego zrobić w CSS.
mikato
Nie, rodzeństwo nie może wpływać na siebie nawzajem. Jednak układ display: table+ display: table-cellprzyniesie pożądany rezultat.
Salman A
Świetna aktualizacja! Jednak skończyło się na tym i chciałem mieć separację białych znaków między divami / komórkami i ostatecznie musiałem wykonać wewnętrzne divy w divach komórek tabeli, aby to osiągnąć, a potem oczywiście straciłem możliwość zmuszenia ich do korzystania z pełnej wysokości ponieważ wewnętrzne divy nie były divami komórkowymi - dokładnie ten sam problem. Jakieś pomysły na to? Trochę brakuje teraz odstępów między komórkami.
mikato
Ach, w CSS występują odstępy między krawędziami! stackoverflow.com/questions/339923/ ... Udało mi się sprawić, że moje div-tabele działały dobrze z separacją białych znaków za pomocą odstępów między ramkami. Teraz mogę sprawić, by komórki tabeli (kolorowe bloki tła) używały pełnej wysokości elementu nadrzędnego lub nie, dzięki sprytnemu użyciu div komórek tabeli.
mikato
Po prostu mam problem, na który wpadłem: nie możesz tego używać z float: stackoverflow.com/questions/20110217/…
Joshua Pinter
4

Ostatnio zrobiłem to na mojej stronie przy użyciu jQuery. Kod oblicza wysokość najwyższego div i ustawia pozostałe div na tę samą wysokość. Oto technika:

http://www.broken-links.com/2009/01/20/very-quick-equal-height-columns-in-jquery/

Nie wierzę, height:100%że zadziała, więc jeśli nie znasz wyraźnie wysokości podziałów, nie sądzę, że istnieje czyste rozwiązanie CSS.

ajcw
źródło
1
Powinieneś uruchomić to przynajmniej przy gotowości, zmianie rozmiaru, zmianie orientacji, zmianie rozmiaru czcionki.
netAction
4

Użyłem tego w sekcji komentarzy:

.parent {
    display: flex;
    float: left;
    border-top:2px solid black;
    width:635px;
    margin:10px 0px 0px 0px;
    padding:0px 20px 0px 20px;
    background-color: rgba(255,255,255,0.5);
}
    
.child-left {
	align-items: stretch;
	float: left;
	width:135px;
	padding:10px 10px 10px 0px;
	height:inherit;
	border-right:2px solid black;
}

.child-right {
	align-items: stretch;
	float: left;
	width:468px;
	padding:10px;
}
<div class="parent">
  <div class="child-left">Short</div>
  <div class="child-right">Tall<br>Tall</div>
</div>

Możesz przesunąć dziecko w prawo, ale w tym przypadku dokładnie obliczyłem szerokość każdego diva.

larsgrafik
źródło
1
pierwszą rzeczą, która przyszła mi do głowy, była wysokość: odziedziczyć nie jestem pewien, dlaczego nikt nie głosował
Andreas
3

Jeśli znasz bootstrap, możesz to łatwo zrobić za pomocą właściwości „flex”. Wystarczy, że podasz właściwości css do rodzica div

.homepageSection {
  overflow: hidden;
  height: auto;
  display: flex;
  flex-flow: row;
}

gdzie .homepageSectionjest mój rodzic div. Teraz dodaj div div w swoim HTML jako

<div class="abc col-md-6">
<div class="abc col-md-6">

gdzie abc jest moim div dziecka. Możesz sprawdzić równość wysokości w obu div dziecka, niezależnie od granicy, po prostu nadając granicy div dziecka

Naved Ali
źródło
0
<div class="parent" style="height:500px;">
<div class="child-left floatLeft" style="height:100%">
</div>

<div class="child-right floatLeft" style="height:100%">
</div>
</div>

Użyłem stylu inline tylko po to, aby dać pomysł.

suketup
źródło
-2

Dowiedziałem się o tej zgrabnej sztuczce podczas rozmowy o staż. Pierwotne pytanie brzmi: w jaki sposób zapewnić wysokość każdego górnego komponentu w trzech kolumnach o tej samej wysokości, która pokazuje całą dostępną zawartość. Zasadniczo utwórz niewidoczny komponent podrzędny, który renderuje maksymalną możliwą wysokość.

<div class="parent">
    <div class="assert-height invisible">
        <!-- content -->
    </div>
    <div class="shown">
        <!-- content -->
    </div>
</div>
Joel Lim
źródło