Spraw, aby div (wysokość) zajmował pozostałą wysokość rodzica


108

http://jsfiddle.net/S8g4E/

Mam pojemnik divz dwójką dzieci. Pierwsze dziecko ma określony wzrost. Jak sprawić, aby drugie dziecko zajmowało „wolną przestrzeń” pojemnika divbez podawania określonej wysokości?

W tym przykładzie różowy divpowinien zajmować również białą przestrzeń.


Podobne do tego pytania: jak sprawić, by div zajmował pozostałą wysokość?

Ale nie chcę podawać pozycji absolutnej .


Próbowałem też, podając wzrost drugiego dziecka 100%, ale nie działa: jsfiddle.net/S8g4E/1
— Alvaro

Odpowiedzi:


156

Rozszerzanie #downdziecka, aby wypełnić pozostałą przestrzeń, #containermożna osiągnąć na różne sposoby, w zależności od obsługi przeglądarki, którą chcesz osiągnąć i od tego, czy #upma określoną wysokość, czy nie .

Próbki

Krata

gridUkład CSS oferuje jeszcze jedną opcję, chociaż może nie być tak prosta jak model Flexbox. Jednak wymaga tylko stylizacji elementu kontenera:

.container { display: grid; grid-template-rows: 100px }

Plik grid-template-rowsWyznacza pierwszy wiersz w postaci stałej 100px wysokości i pozostają rzędy rozciągają się automatycznie wypełniając pozostałą przestrzeń.

Jestem prawie pewien, że IE11 wymaga -ms-prefiksów, więc upewnij się, że sprawdziłeś funkcjonalność w przeglądarkach, które chcesz obsługiwać.

Flexbox

Modułflexbox CSS3 Flexible Box Layout Module ( ) jest teraz dobrze obsługiwany i może być bardzo łatwy do wdrożenia. Ponieważ jest elastyczny, działa nawet wtedy, gdy #upnie ma określonej wysokości.

#container { display: flex; flex-direction: column; }
#down { flex-grow: 1; }

Ważne jest, aby pamiętać, że obsługa IE10 i IE11 dla niektórych właściwości flexboksa może być wadliwa, a IE9 lub starsze nie mają żadnej obsługi.

Obliczona wysokość

Innym łatwym rozwiązaniem jest użycie jednostki funkcjonalnej CSS3calc , jak wskazuje Alvaro w swojej odpowiedzi , ale wymaga, aby wzrost pierwszego dziecka był znaną wartością:

#up { height: 100px; }
#down { height: calc( 100% - 100px ); }

Jest dość szeroko obsługiwany, z jedynymi godnymi uwagi wyjątkami: <= IE8 lub Safari 5 (brak wsparcia) i IE9 (częściowe wsparcie). Niektóre inne problemy obejmują używanie programu calc w połączeniu z transform lub box-shadow , więc jeśli Cię to niepokoi, upewnij się, że wykonałeś test w wielu przeglądarkach.

Inne alternatywy

Jeśli potrzebne jest wsparcie starszych, można dodać height:100%;do #downuczyni różową div pełnej wysokości, z jednym zastrzeżeniem. Spowoduje to przepełnienie pojemnika, ponieważ #uppopycha go w dół.

Dlatego możesz dodać overflow: hidden;do kontenera, aby to naprawić.

Alternatywnie, jeśli wysokość #upjest stała, możesz umieścić ją całkowicie w pojemniku i dodać wyściółkę do #down.

A jeszcze inną opcją byłoby użycie wyświetlacza tabeli:

#container { width: 300px; height: 300px; border: 1px solid red; display: table;}
#up { background: green; display: table-row; height: 0; }
#down { background: pink; display: table-row;}​

4
Chciałbym, aby # dół miał # wysokość kontenera - # wysokość w górę. Więc ukryty przepełnienie nie jest tym, czego szukam. A także nie chcę używać pozycji bezwzględnej. Dzięki!
— Alvaro

@Alvaro, dodałem kolejną opcję, używając wyświetlaczy tabelowych. Wadą jest tutaj kompatybilność. PS Element umieszczony absolutnie wewnątrz kontenera i position: relative;pozycjonuje go względem kontenera, a nie okna. To powinno być realną opcją.
— użytkownik

2
Wiersz tabeli powinien działać dla Ciebie, zobacz ten jsFiddle, aby uzyskać dowód. Metoda pozycji bezwzględnej nie będzie w stanie dać takich samych wyników, jak te skrzypce, więc możemy usunąć to z listy (# w dół i #container będą miały taką samą wysokość w tym scenariuszu).
— użytkownik

3
Dużo prosisz @Alvaro. CSS nie jest językiem skryptowym; nie potrafi obliczyć rzeczy. Utkniesz z iluzjami lub js.
— Jezen Thomas

1
@Quantastical, dziękuję za pomoc, ale w swojej ostatniej edycji właśnie skopiowałeś odpowiedź, którą opublikowałem. Jakaś wzmianka o tym przynajmniej byłaby miła.
— Alvaro

24

Minęły prawie dwa lata, odkąd zadałem to pytanie. Właśnie wymyśliłem css calc (), które rozwiązuje ten problem, który miałem i pomyślałem, że byłoby miło dodać go na wypadek, gdyby ktoś miał ten sam problem. (Nawiasem mówiąc, ostatecznie użyłem pozycji bezwzględnej).

http://jsfiddle.net/S8g4E/955/

Oto plik css

#up { height:80px;}
#down {
    height: calc(100% - 80px);//The upper div needs to have a fixed height, 80px in this case.
}

Więcej informacji na ten temat znajdziesz tutaj: http://css-tricks.com/a-couple-of-use-cases-for-calc/

Obsługa przeglądarek: http://caniuse.com/#feat=calc


1
Ja też używałem CSS3, calcgdzie obsługa szerokiej przeglądarki nie jest tak ważna (IE8 i starsze oraz Safari 5 nie obsługują tego).
— użytkownik

3
Jakiś sposób zrobić coś podobnego z dynamiczną #upwysokością?
— Adam Waite

@AdamWaite, z dynamiczną wysokością # up, będziesz chciał użyć rozwiązania przepełnienia opisanego w innej odpowiedzi.
— użytkownik

5

Moja odpowiedź używa tylko CSS i nie używa overflow: hidden ani display: table-row. Wymaga to, aby pierwsze dziecko naprawdę miało określony wzrost, ale w swoim pytaniu stwierdzasz, że tylko drugie dziecko musi mieć nieokreślony wzrost, więc uważam, że powinieneś to zaakceptować.

html

<div id="container">
    <div id="up">Text<br />Text<br />Text<br /></div>
    <div id="down">Text<br />Text<br />Text<br /></div>
</div>

css

#container { width: 300px; height: 300px; border:1px solid red;}
#up { background: green; height: 63px; float:left; width: 100% }
#down { background:pink; padding-top: 63px; height: 100%; box-sizing: border-box; }

http://jsfiddle.net/S8g4E/288/


3

Abstrakcyjny

Nie znalazłem w pełni satysfakcjonującej odpowiedzi, więc musiałem sam się tego dowiedzieć.

Moje wymagania:

  • element powinien zajmować dokładnie pozostałą przestrzeń, albo gdy rozmiar jego zawartości jest mniejszy lub większy niż pozostały rozmiar przestrzeni (w drugim przypadku powinien być pokazany pasek przewijania );
  • rozwiązanie powinno działać, gdy wysokość rodzica jest obliczana , a nie określona ;
  • calc()nie należy używać, ponieważ pozostały element nie powinien nic wiedzieć o innych rozmiarach elementów;
  • Należy stosować nowoczesne i znane techniki projektowania, takie jak flexboxy .

Rozwiązanie

  • Zamień na flexboxy wszystkich bezpośrednich rodziców z obliczoną wysokością (jeśli istnieją) i następnego rodzica, którego wysokość jest określona ;
  • Określ flex-grow: 1dla wszystkich bezpośrednich rodziców z wyliczoną wysokością (jeśli istnieje) i elementem aby zajmowały całą pozostałą przestrzeń, gdy rozmiar zawartości elementu jest mniejszy;
  • Określ flex-shrink: 0dla wszystkich elementów elastycznych o stałej wysokości aby nie zmniejszyły się, gdy rozmiar zawartości elementu jest większy niż pozostały rozmiar przestrzeni;
  • Określ overflow: hiddendla wszystkich bezpośrednich rodziców z obliczoną wysokością (jeśli istnieje), aby wyłączyć przewijanie i zabronić wyświetlania zawartości przepełnienia;
  • Określ overflow: autodo elementu , aby umożliwić przewijanie wewnątrz niego.

JSFiddle (element ma bezpośrednich rodziców z wyliczoną wysokością)

JSFiddle (prosty przypadek: brak bezpośrednich rodziców z obliczoną wysokością)


2

sprawdź demo - http://jsfiddle.net/S8g4E/6/

użyj css -

#container { width: 300px; height: 300px; border:1px solid red; display: table;}
#up { background: green; display: table-row; }
#down { background:pink; display: table-row;}

Należy dodać height: 1pxdo, #upaby mieć pewność, że zajmuje minimalną wysokość. Oto obsługa przeglądarki dla display: table: caniuse.com/css-table
— thirtydot.

Czy mógłbyś mi pokazać, jak można osiągnąć to rozwiązanie w tym „bardziej złożonym” przykładzie: jsfiddle.net/fyNX4 Dziękuję bardzo
— Alvaro

2

Chyba że się nie rozumiem, możesz po prostu dodać height: 100%;i overflow:hidden;do #down.

#down { 
    background:pink; 
    height:100%; 
    overflow:hidden;
}​

DEMO na żywo

Edycja: ponieważ nie chcesz używać overflow:hidden;, możesz użyć display: table;w tym scenariuszu; jednak nie jest obsługiwany przed IE 8. ( display: table;wsparcie )

#container { 
    width: 300px; 
    height: 300px; 
    border:1px solid red;
    display:table;
}

#up { 
    background: green;
    display:table-row;
    height:0; 
}

#down { 
    background:pink;
    display:table-row;
}​

DEMO na żywo

Uwaga: Powiedziałeś, że chcesz, aby #downwysokość była równa #containerwysokości minus #upwysokość. display:table;Rozwiązanie robi dokładnie to i to jsfiddle wcieli że dość wyraźnie.


1
Nie chcę, aby # dół przekroczył wysokość # kontenera
— Alvaro,

Właśnie to zauważyłem. Możesz dodać overflow:hiddendo, aby ukryć dodatkową zawartość.
— Josh Mein

1
Skopiuję / wkleję to, co powiedziałem do MrSlayera: chciałbym, aby # dół miał # wysokość kontenera - # wysokość w górę. Więc ukryty przepełnienie nie jest tym, czego szukam. A także nie chcę używać pozycji bezwzględnej. Dzięki!
— Alvaro

Problem polega na tym, że jeśli w przykładzie odwrócisz dwa elementy div, zielony element div znajduje się na zewnątrz.
— środa,

To wcale nie odpowiada na pytanie. Mówi „Aby zająć całą pozostałą wysokość”, nawet jeśli zajmie całą pozostałą wysokość, nastąpi przepełnienie.
— Giridhar Karnik

1

Możesz używać pływaków do wypychania zawartości w dół:

http://jsfiddle.net/S8g4E/5/

Masz kontener o stałym rozmiarze:

#container {
    width: 300px; height: 300px;
}

Treść może przepływać obok pływaka. O ile nie ustawimy pływaka na pełną szerokość:

#up {
    float: left;
    width: 100%;
}

Podczas gdy #upi #downudostępnij najwyższą pozycję, #downzawartość może zaczynać się tylko po dolnej części pływającej #up:

#down {
    height:100%;
}​

Zauważ, że #upfaktycznie obejmuje górną część #down: jsfiddle.net/thirtydot/S8g4E/9
— thirtydot.

Tak, tak to działa. Ale jeśli OP nie potrzebuje zaokrąglonej ramki lub czegoś innego #up, to prawdopodobnie jest to akceptowalne.
— biziclop,

To rozwiązanie jest bliskie, ale chciałbym, aby # dół miał # wysokość kontenera - # wysokość do góry. (W twoim rozwiązaniu # wysokość w dół = # wysokość kontenera). Dzięki ”
— Alvaro,

1
@Alvaro: Dlaczego tak musi być? To rozwiązanie w większości przypadków wygląda poprawnie, nawet jeśli jest tylko złudzeniem.
— thirtydot

Cóż, to pytanie jest uproszczonym przykładem z tego bardziej „złożonego” przykładu: jsfiddle.net/fyNX4 Nie zadziała, prawda?
— Alvaro

-3

Nie jestem pewien, czy można to zrobić wyłącznie za pomocą CSS, chyba że czujesz się komfortowo w udawaniu iluzji. Może używać odpowiedź Josh mein, a zestaw #containerdooverflow:hidden .

Oto rozwiązanie jQuery:

var contH = $('#container').height(),
upH = $('#up').height();
$('#down').css('height' , contH - upH);

Dzięki, szukałem czystego rozwiązania CSS.
— Alvaro
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.