Jak zmusić div dziecka do 100% wzrostu div div bez określania wzrostu rodzica?

535

Mam witrynę o następującej strukturze:

<div id="header"></div>

<div id="main">
  <div id="navigation"></div>
  <div id="content"></div>
</div>

<div id="footer"></div>

Nawigacja znajduje się po lewej stronie, a div treści po prawej. Informacje dla div treści są pobierane przez PHP, więc za każdym razem są inne.

Jak przeskalować nawigację w pionie, aby jej wysokość była taka sama jak wysokość div zawartości, bez względu na to, która strona jest załadowana?

TylerH
źródło
1
Użyj tabeli wyświetlania na obiekcie nadrzędnym i wyświetl komórkę tabeli na obiekcie podrzędnym. To sprawi, że dziecko będzie tak długo, jak rodzic. Zobacz stackoverflow.com/q/22712489/3429430
user31782,
3
Możesz po prostu ustawić display: flex; align-items: stretch;dla div # main. I nie używaj height: 100%do treści div #
Igor

Odpowiedzi:

167

UWAGA : Ta odpowiedź dotyczy starszych przeglądarek bez obsługi standardu Flexbox. Aby uzyskać nowoczesne podejście, zobacz: https://stackoverflow.com/a/23300532/1155721


Sugeruję przyjrzeć się kolumnom o jednakowej wysokości z CSS między przeglądarkami i bez hacków .

Zasadniczo robienie tego za pomocą CSS w sposób zgodny z przeglądarką nie jest trywialne (ale trywialne z tabelami), więc znajdź sobie odpowiednie wstępnie zapakowane rozwiązanie.

Odpowiedź zależy również od tego, czy chcesz 100% wysokości, czy równej wysokości. Zwykle jest równa wysokość. Jeśli ma 100% wysokości, odpowiedź jest nieco inna.

Cletus
źródło
7
Wygląda to na dobre rozwiązanie, dopóki nie narysujesz ramki, border:1px solid bluenp . container2: niebieska ramka znajduje się na pierwszych dwóch kolumnach, a nie w drugiej kolumnie tylko tak, jak można się spodziewać.
Julien Kronegg,
@bfritz, lepszym rozwiązaniem byłoby użyciedisplay:table
Siler
537

Dla rodzica:

display: flex;

Powinieneś dodać kilka prefiksów, http://css-tricks.com/using-flexbox/ .

Edycja: Jak zauważył @Adam Garner, wyrównaj elementy: rozciągnij; nie jest potrzebne. Jego użycie jest również dla rodziców, a nie dzieci. Jeśli chcesz zdefiniować rozciąganie dzieci, użyj align-self.

.parent {
  background: red;
  padding: 10px;
  display:flex;
}

.other-child {
  width: 100px;
  background: yellow;
  height: 150px;
  padding: .5rem;
}

.child {  
  width: 100px;
  background: blue;
}
<div class="parent">
  <div class="other-child">
    Only used for stretching the parent
  </div>
  <div class="child"></div>
</div>

Aiphee
źródło
3
IE11 nie działa ładnie z Flexbox i wysokościami. kliknij „znane problemy” tutaj: caniuse.com/#feat=flexbox
adamdport
@SuperUberDuper Cóż, możesz użyć go w bootstrap w następujący sposób: jsfiddle.net/prdwaynk Ale gdybym był tobą, użyłbym fundamentu, który jest gotowy do produkcji z Flexbox: Foundation.zurb.com/sites/docs/xy-grid.html BS4 będzie także miał Flexboksa, ale wciąż jest w wersji alfa i myślę, że fundament i tak jest lepszy.
Aiphee,
4
Jeśli używasz align-items: center, potrzebny jest element, który musisz rozciągnąćalign-self: normal
Dominic
2
To nie jest poprawna odpowiedź, ponieważ musi to ustawić wysokość rodzica. Pytanie brzmiało: „nie określając wzrostu rodzica?”.
SkuraZZ
3
@Aiphee downvoting, ponieważ wygląda na to, że nie widziałeś części o tym, że nie musisz ustawiać wysokości rodziców w oryginalnym tekście pytania, ale twoje „rozwiązanie” robi dokładnie to.
tyleryzm
98

To frustrujący problem, z którym cały czas zajmują się projektanci. Sztuka polega na tym, że musisz ustawić wysokość na 100% na BODY i HTML w swoim CSS.

html,body {
    height:100%;
}

Ten pozornie bezcelowy kod ma zdefiniować w przeglądarce, co oznacza 100%. Frustrujące, tak, ale to najprostszy sposób.

Travis
źródło
8
Tyle że nie zawsze działa, na przykład jeśli masz element pozycjonowany względnie wewnątrz elementu pozycjonowanego absolutnie, nie wymusza już hasLayout.
tim
Również, jeśli chcesz pozbyć się pasek przewijania po prawej stronie okna (pojawia się w Firefoksie V28) dają okno jakiś pokój oddechowe html { height: 100%; } body { height: 98%; }.
Chris Middleton
58
Działa to tylko wtedy, gdy wszyscy rodzice mają wysokość 100%, nie wystarczy ustawić tylko HTML i ciało, wszyscy rodzice muszą mieć zdefiniowaną wysokość.
RaduM
96

Uważam, że ustawienie dwóch kolumn na display: table-cell;zamiast float: left;działa dobrze.

Paul Harvey
źródło
9
Same stwardnienie rozsiane już nie popierają tego, jeśli to pomaga komukolwiek przekonać swoich klientów ...
Heraldmonkey
3
To powinna być zaakceptowana odpowiedź. Czasy się zmieniły, ta odpowiedź działa we wszystkich przeglądarkach (z małym dziwactwem w Safari 5.1.17). Dwie linie CSS i od razu masz efekt, którego szukasz, bez żadnych wycofań, o których mogę myśleć.
callmetwan
6
Podnieś tę odpowiedź. Połóżcie się na plecach chłopaki!
To najlepsza odpowiedź. Tak, możemy zrobić tabelę, aby to zrobić, ale nie są to dane tabelaryczne, zamiast tego traktujemy div tak, jakby były komórkami tabeli ... Genialne!
Derokorian
To faktycznie skierowało mnie w dobrym kierunku na inny scenariusz. W przypadku, gdy ktoś stara się pracować z kwadratowymi divami, które są również elastycznymi kontenerami w Firefox lub Edge, pamiętaj tylko o ustawieniu elementu: before na display: table. Nie pytaj mnie dlaczego, ale to naprawia.
CGodo,
55

Jeśli nie przeszkadza to, że div nawigacji zostanie przycięty w przypadku nieoczekiwanie krótkiego div treści, istnieje co najmniej jeden prosty sposób:

#main {
position: relative;
}

#main #navigation {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 10em; /* or whatever */
}

#main #content {
margin: 0;
margin-left: 10em; /* or whatever width you set for #navigation */
}

W przeciwnym razie istnieje technika sztucznych kolumn .

David mówi, że przywraca Monikę
źródło
2
Dzięki tona, uratowałeś mi dzień. Nie wiedziałem, że można zdefiniować zarówno górny, jak i dolny i tak to zadziała.
rubish
Spowoduje to, że zawartość kontenera przestanie go zmieniać.
DreamWave,
+1, ponieważ konkretnie odpowiada na pytanie PO: „Jak zmusić Div dziecka do 100% Div Diva bez określania wzrostu rodzica?” Mój problem nie wymagał kolumn (które są wymienione w szczegółach pytania, ale nie w głównym nagłówku), ale raczej jednego diva za drugim. Ta odpowiedź działa w obu aplikacjach.
Łukasza
To powinna być wybrana odpowiedź
Gabriel
31
#main {
    overflow: hidden;
}
#navigation, #content {
    margin-bottom: -1000px;
    padding-bottom: 1000px;
}
Roman Kuntyi
źródło
Muszę powiedzieć, że szukałem tego rodzaju rozwiązania. Zupełnie proste i tak oczywiste, że nikt tego nie rozgryzł. Gratulacje @Roman!
Greg0ry
15

przy użyciu jQuery:

$(function() {
    function unifyHeights() {
        var maxHeight = 0;
        $('#container').children('#navigation, #content').each(function() {
            var height = $(this).outerHeight();
            // alert(height);
            if ( height > maxHeight ) {
                maxHeight = height;
            }
        });
        $('#navigation, #content').css('height', maxHeight);
    }
    unifyHeights();
});
Flavius
źródło
19
Math.max()byłby tu twój przyjaciel.
alex
1
Nie mogłem zmusić CSS do działania we wszystkich przypadkach. Naprawdę potrzebowałem tylko szybkiej poprawki. To może nie być najbardziej standardowe podejście, ale dobrze się spisało. Dzięki! : -]
1
Korzystając z cssfunkcji JQuery , nie można rozróżniać ekranu i nośników wydruku, jak zwykle w przypadku korzystania z czystych rozwiązań CSS. Dlatego możesz mieć problemy z drukowaniem.
Julien Kronegg,
12

Spróbuj ustawić dolny margines na 100%.

margin-bottom: 100%;
Tony C.
źródło
6
lub wyściełane dno: 100%; nie jest precyzyjny, ale działa dobrze w niektórych sytuacjach.
Jason
padding-bottom robi lewę w moim przypadku. To rozwiązanie jest bardzo podobne do tego, co napisał @Roman Kuntyi.
Greg0ry
10
#main {
   display: table;
} 
#navigation, #content {
   display: table-cell;
}

Spójrz na ten przykład .

Sergiu
źródło
Właśnie to robiłem, chciałem dodać odpowiedź. Ja również używałem, height: 100%ale okazało się, że nie było to potrzebne.
jcubic
9

height : <percent>będzie działać tylko wtedy, gdy wszystkie najwyższe węzły mają wszystkie węzły nadrzędne o określonej wysokości i stałej wysokości w pikselach, ems itp. W ten sposób wysokość spadnie kaskadowo do twojego elementu.

Możesz określić 100% do HTML i elementów treści, jak podano wcześniej @Travis, aby wysokość strony spadała kaskadowo do twoich węzłów.

Lajos Meszaros
źródło
9

Po długich poszukiwaniach i próbach nic nie rozwiązało mojego problemu

style = "height:100%;"

na div dzieci

i dla rodziców zastosuj to

.parent {
    display: flex;
    flex-direction: column;
}

również używam bootstrap i to nie uszkodziło responsywnego dla mnie.

Hakan Fıstık
źródło
1
Musiałem usunąć, flex-direction: column;aby to działało dla mnie.
Richard Hedges,
6

Na podstawie metody opisanej w tym artykule stworzyłem .Mniejsze rozwiązanie dynamiczne:

HTML:

<div id="container3">
    <div id="container2">
        <div id="container1">
            <div id="col1">Column 1</div>
            <div id="col2">Column 2</div>
            <div id="col3">Column 3</div>
        </div>
    </div>
</div>

Mniej:

/* Changes these variables to adjust your columns */
@col1Width: 60%;
@col2Width: 1%;
@padding: 0%;

/* Misc variable. Do not change */
@col3Width: 100% - @col1Width - @col2Width;

#container3 {
    float: left;
    width: 100%;
    overflow: hidden;
    background-color: red;
    position: relative;

    #container2 {
        float: left;
        width: 100%;
        position: relative;
        background-color: yellow;
        right: @col3Width;

        #container1 {
            float: left;
            width: 100%;
            position: relative;
            right: @col2Width;
            background-color: green;

            #col1 {
                float: left;
                width: @col1Width - @padding * 2;
                position: relative;
                left: 100% - @col1Width + @padding;
                overflow: hidden;
            }

            .col2 {
                float: left;
                width: @col2Width - @padding * 2;
                position: relative;
                left: 100% - @col1Width + @padding + @padding * 2;
                overflow: hidden;
            }

            #col3 {
                float: left;
                width: @col3Width - @padding * 2;
                position: relative;
                left: 100% - @col1Width + @padding + @padding * 4;
                overflow: hidden;
            }
        }
    }
}
Dmitrij Efimenko
źródło
4

Dodaj display: griddo rodzica

Dziamid
źródło
3

Wiem, że minęło dużo czasu, odkąd pytanie zostało zadane, ale znalazłem łatwe rozwiązanie i pomyślałem, że ktoś może go użyć (przepraszam za słaby angielski). Oto jest:

CSS

.main, .sidebar {
    float: none;
    padding: 20px;
    vertical-align: top;
}
.container {
    display: table;
}
.main {
    width: 400px;
    background-color: LightSlateGrey;
    display: table-cell;
}
.sidebar {
    width: 200px;
    display: table-cell;
    background-color: Tomato;
}

HTML

<div class="container clearfix">
    <div class="sidebar">
        simple text here
    </div>
    <div class="main">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam congue, tortor in mattis mattis, arcu erat pharetra orci, at vestibulum lorem ante a felis. Integer sit amet est ac elit vulputate lobortis. Vestibulum in ipsum nulla. Aenean erat elit, lacinia sit amet adipiscing quis, aliquet at erat. Vivamus massa sem, cursus vel semper non, dictum vitae mi. Donec sed bibendum ante.
    </div>
</div>

Prosty przykład. Pamiętaj, że możesz zmienić się w responsywność.

Paula Fleck
źródło
Och, zapomniałem: jeśli chcesz wyrównać zawartość paska bocznego na środku, po prostu zmień ustawienie „vertical-align: top” na „vertical-align: middle”.
Paula Fleck
2

Moje rozwiązanie:

$(window).resize(function() {
   $('#div_to_occupy_the_rest').height(
        $(window).height() - $('#div_to_occupy_the_rest').offset().top
    );
});
Rafael Ruiz Muñoz
źródło
1

Jest trochę sprzeczności w tytule pytania i treści. Tytuł mówi o rodzicielskiej div, ale pytanie brzmi, jakbyś chciał, aby dwie divy rodzeństwa (nawigacja i treść) były tej samej wysokości.

Czy (a) chcesz, aby nawigacja i treść były w 100% wysokości głównej, czy (b) chcesz, aby nawigacja i treść były tej samej wysokości?

Zakładam (b) ... jeśli tak jest, nie sądzę, że będziesz w stanie to zrobić, biorąc pod uwagę obecną strukturę strony (przynajmniej bez czystego CSS i bez skryptów). Prawdopodobnie będziesz musiał zrobić coś takiego:

<main div>
    <content div>
         <navigation div></div>
    </div>
</div>

i ustaw div treści tak, aby miał lewy margines niezależnie od szerokości panelu nawigacji. W ten sposób zawartość zawartości znajduje się po prawej stronie nawigacji i możesz ustawić div nawigacji na 100% wysokości zawartości.

EDYCJA: Robię to całkowicie w mojej głowie, ale prawdopodobnie musiałbyś również ustawić lewy margines div nawigacji na wartość ujemną lub ustawić absolutną lewą na 0, aby przesunąć go z powrotem w lewo. Problem w tym, że istnieje wiele sposobów, aby to zrobić, ale nie wszystkie będą kompatybilne ze wszystkimi przeglądarkami.

Paul Abbott
źródło
1

[Nawiązując do kodu Dmity's Less w innej odpowiedzi] Zgaduję, że jest to jakiś „pseudo-kod”?

Z tego, co rozumiem, spróbuj użyć techniki faux-kolumny, która powinna załatwić sprawę.

http://www.alistapart.com/articles/fauxcolumns/

Mam nadzieję że to pomoże :)

jluna
źródło
4
W zależności od kolejności sortowania odpowiedzi trudno jest powiedzieć, do czego odnosi się to „to” ... Domyślam się, że chodzi o kod Dmitry'ego. Tak więc ta uwaga należy do komentarza pod jego odpowiedzią! Dla twojej informacji nie jest to pseudo-kod, to kod w języku Less, sposób definiowania CSS w sposób proceduralny.
PhiLho
1

Ta sztuczka działa: Dodanie ostatniego elementu w sekcji HTML ze stylem clear: oba;

    <div style="clear:both;"></div>

Wszystko przed tym będzie wliczone w wysokość.

użytkownik945389
źródło
1

dawanie position: absolute;dziecku działało w moim przypadku

neoDev
źródło
1

Korzystasz z CSS Flexbox

.flex-container {
  display: flex;
  background-color: DodgerBlue;
}

.flex-container > div {
  background-color: #f1f1f1;
  margin: 10px;
  padding: 20px;
  font-size: 30px;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>

<div class="flex-container">
  <div>1</div>
  <div>2</div>
  <div>3</div>  
</div>

<p>A Flexible Layout must have a parent element with the <em>display</em> property set to <em>flex</em>.</p>

<p>Direct child elements(s) of the flexible container automatically becomes flexible items.</p>

</body>
</html>

Ini
źródło
1

Ta odpowiedź nie jest już idealna, ponieważ CSS Flexbox i grid zostały zaimplementowane w CSS. Jednak nadal jest to skuteczne rozwiązanie

Na mniejszym ekranie prawdopodobnie chciałbyś zachować automatyczną wysokość, ponieważ col1, col2 i col3 są ułożone jeden na drugim.

Jednak po punkcie przerwania zapytania o media chciałbyś, aby cols pojawiały się obok siebie z jednakową wysokością dla wszystkich kolumn.

1125 px to tylko przykład punktu przerwania szerokości okna, po którym chcesz ustawić wszystkie kolumny na tę samą wysokość.

<div class="wraper">
    <div class="col1">Lorem ipsum dolor sit amet.</div>
    <div class="col2">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eos laudantium, possimus sed, debitis amet in, explicabo dolor similique eligendi officia numquam eaque quae illo magnam distinctio odio, esse vero aspernatur.</div>
    <div class="col3">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorem, odio qui praesentium.</div>
</div>

W razie potrzeby możesz oczywiście ustawić więcej punktów przerwania.

<script>
    $(document).ready(function(){
        $(window).on('load resize', function() {
            let vraperH = $('.wraper').height();
            if (window.innerWidth>= 1125) {
              $('.col1').height(vraperH);
              $('.col2').height(vraperH);
              $('.col3').height(vraperH);
            }
            if (window.innerWidth < 1125) {
              $('.col1').height('auto');
              $('.col2').height('auto');
              $('.col3').height('auto');
            }
        });
    });
</script>
DevWL
źródło
1

Miałem ten sam problem, działał w oparciu o odpowiedź Hakama Fostoka, stworzyłem mały przykład, w niektórych przypadkach może działać bez konieczności dodawania display: flex;i flex-direction: column;na kontenerze nadrzędnym

.row {
    margin-top: 20px;
}

.col {
    box-sizing: border-box;
    border: solid 1px #6c757d;
    padding: 10px;
}

.card {
    background-color: #a0a0a0;
    height: 100%;
}

JSFiddle

Builo
źródło
0

Jak pokazano wcześniej, Flexbox jest najłatwiejszy. na przykład.

#main{ display: flex; align-items:center;}

spowoduje to wyrównanie wszystkich elementów potomnych do środka w elemencie macierzystym.

Chandan Purohit
źródło
3
to nie odpowiada na pytanie, chcą równej wysokości, nie wyśrodkowując zawartości
Ryan M
0

Oto demo starej mody oparte na position: absolutekontenerze zawartości i position: relativekontenerze nadrzędnym.

Jeśli chodzi o nowoczesny sposób, aby to zrobić - pudełka Flex są najlepsze.

WebBrother
źródło
-3

Najłatwiej to zrobić po prostu sfałszować. List Apart omawiał to obszernie na przestrzeni lat, podobnie jak w tym artykule Dan Cederholm z 2004 roku .

Oto jak zwykle to robię:

<div id="container" class="clearfix" style="margin:0 auto;width:950px;background:white url(SOME_REPEATING_PATTERN.png) scroll repeat-y center top;">
    <div id="navigation" style="float:left;width:190px;padding-right:10px;">
        <!-- Navigation -->
    </div>
    <div id="content" style="float:left;width:750px;">
        <!-- Content -->
    </div>
</div>

Możesz łatwo dodać nagłówek do tego projektu, zawijając #container w inny div, osadzając div nagłówka jako rodzeństwo # kontenera i przenosząc style marginesów i szerokości do kontenera nadrzędnego. Ponadto CSS powinien zostać przeniesiony do osobnego pliku, a nie przechowywany w linii itd. Itd. Na koniec klasa clearfix znajduje się na pozycji .

Aaron Brethorst
źródło