Как сделать так, чтобы дочерний div был равен 100% высоты родительского div без указания высоты родителя?

535

У меня есть сайт со следующей структурой:

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

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

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

Навигация находится слева, а раздел содержимого - справа. Информация для содержимого div передается через PHP, поэтому каждый раз она меняется.

Как я могу масштабировать навигацию по вертикали, чтобы ее высота совпадала с высотой содержимого div, независимо от того, какая страница загружена?

TylerH
источник
1
Используйте display table на родительском элементе и display-cell-table на дочернем. Это сделает ребенка таким же, как и родитель. См stackoverflow.com/q/22712489/3429430
user31782
3
Вы можете просто установить display: flex; align-items: stretch;для div # main. И не используйте height: 100%для содержимого div #
Игорь

Ответы:

167

ПРИМЕЧАНИЕ . Этот ответ применим к устаревшим браузерам без поддержки стандарта Flexbox. Для современного подхода, см .: https://stackoverflow.com/a/23300532/1155721


Я предлагаю вам взглянуть на столбцы одинаковой высоты с кросс-браузерным CSS и без хаков .

По сути, делать это с помощью CSS совместимым с браузером способом не тривиально (но тривиально с таблицами), поэтому найдите себе подходящее готовое решение.

Кроме того, ответ зависит от того, хотите ли вы 100% высоты или равной высоты. Обычно это равная высота. Если это 100% высота, ответ немного другой.

Клетус
источник
7
Это выглядит как хорошее решение, пока вы не нарисуете границу, border:1px solid blueнапример container2: синяя рамка находится на первых двух столбцах, а не на втором столбце, как вы ожидали.
Жюльен Кронегг
@bfritz, лучшее решение было бы использоватьdisplay:table
Siler
538

Для родителя:

display: flex;

Вы должны добавить некоторые префиксы, http://css-tricks.com/using-flexbox/ .

Изменить: как заметил @ Адам Гарнер, выровнять элементы: растянуть; не нужен Его использование также для родителей, а не детей. Если вы хотите определить растяжение детей, вы используете 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
источник
3
IE11 плохо работает с flexbox и высотами. нажмите на «известные проблемы» здесь: caniuse.com/#feat=flexbox
adamdport
@SuperUberDuper Ну, вы можете использовать его в начальной загрузке, как это: jsfiddle.net/prdwaynk Но на вашем месте я бы использовал фундамент, готовый к работе с flexbox: foundation.zurb.com/sites/docs/xy-grid.html BS4 также будет иметь Flexbox, но он все еще находится в альфа-версии, и я думаю, что фундамент в любом случае лучше.
Айфи
4
Если вы используете align-items: centerто, что нужно растянуть,align-self: normal
Доминик,
2
Это неправильный ответ, потому что для этого нужно установить родительскую высоту. Вопрос сказал «без указания роста родителей?».
SkuraZZ
3
@ Aiphee понижает голосование, потому что кажется, что вы не видели части о том, что вам не нужно устанавливать родительский рост прямо в исходном тексте вопроса, но ваше «решение» делает именно это.
Тайлеризм
99

Это неприятная проблема, с которой постоянно сталкиваются дизайнеры. Хитрость в том, что вам нужно установить высоту 100% для тела и HTML в вашем CSS.

html,body {
    height:100%;
}

Этот, казалось бы, бессмысленный код должен определять браузеру, что означает 100%. Разочарование, да, но это самый простой способ.

Travis
источник
9
За исключением того, что он не всегда работает, например, если у вас есть элемент с относительным позиционированием внутри элемента с абсолютным позиционированием, он больше не вызывает hasLayout.
Тим
Кроме того , если вы хотите избавиться от скроллинга в правой части окна (появится в Firefox V28), дать окно некоторую передышку: html { height: 100%; } body { height: 98%; }.
Крис Миддлтон
59
Это работает, только если все родители имеют рост 100%, недостаточно указать только HTML и тело, все родители должны иметь определенную высоту.
RaduM
97

Я считаю, что установка двух столбцов display: table-cell;вместо того, чтобы float: left;работать хорошо.

Пол Харви
источник
10
Сами MS больше не поддерживают это, если это поможет кому-нибудь убедить своих клиентов ...
Heraldmonkey
4
Это должен быть принятый ответ. Времена изменились, этот ответ работает во всех браузерах (в том числе в Safari 5.1.17). Две линии CSS, и вы мгновенно получаете эффект, который вы ищете, без отступлений, о которых я могу думать.
callmetwan
7
Поднимите этот ответ. Положи свои спины в нее, ребята!
Это лучший ответ. Да, мы можем сделать таблицу для этого, но это не табличные данные, вместо этого мы рассматриваем div как если бы они были ячейками таблицы ... Отлично!
Derokorian
Это фактически поставило меня в правильном направлении для другого сценария. В случае, если кто-то изо всех сил пытается работать с квадратными div, которые также являются гибкими контейнерами в Firefox или Edge, просто не забудьте установить элемент: before для отображения: table. Не спрашивайте меня почему, но это исправляет.
CGodo
56

Если вы не возражаете против того, чтобы div навигации был обрезан в случае неожиданно короткого содержимого div, есть по крайней мере один простой способ:

#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 */
}

В противном случае есть техника искусственных колонн .

Дэвид говорит восстановить Монику
источник
2
Огромное спасибо, ты спас мой день. Не знал, что можно определить верх и низ, и это сработает так.
руби
Это заставит содержимое контейнера перестать изменять его размер.
DreamWave
+1, потому что он конкретно отвечает на вопрос ОП «Как принудить Div ребенка к 100% Div родителя без указания роста родителя?» Моя проблема не требовала столбцов (которые упоминаются в деталях вопроса, но не в главном заголовке), а один разделитель за другим. Этот ответ работает в обоих приложениях.
Лука
Это должен быть выбранный ответ
Габриэль
32
#main {
    overflow: hidden;
}
#navigation, #content {
    margin-bottom: -1000px;
    padding-bottom: 1000px;
}
Роман Кунти
источник
Я должен сказать, что искал такое решение. Умер просто и так очевидно, что никто не понял этого. Поздравляю @Roman!
Грегори
15

используя 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();
});
Флавий
источник
19
Math.max()был бы вашим другом здесь.
Алекс
1
Не удалось заставить CSS работать во всех случаях, мне просто нужно было быстрое решение. Возможно, это не самый стандартный подход, но он отлично справился со своей задачей. Спасибо! : -]
1
При использовании cssфункции JQuery вы не можете различить экранные и печатные носители, как это обычно делается при использовании чисто CSS-решений. Таким образом, у вас могут возникнуть проблемы с печатью.
Жюльен Кронегг
12

Попробуйте сделать нижнее поле 100%.

margin-bottom: 100%;
Тони С
источник
6
или отступы: 100%; это не точно, но это хорошо работает для некоторых ситуаций.
Джейсон
padding-bottom делает свое дело в моем случае. Это решение очень похоже на то, что написал @Roman Kuntyi.
Грегори
10
#main {
   display: table;
} 
#navigation, #content {
   display: table-cell;
}

Посмотрите на этот пример .

Серджиу
источник
Это именно то, что я делал, хотел добавить ответ. Я тоже использовал, height: 100%но оказалось, что это было не нужно.
jcubic
9

height : <percent>будет работать, только если у вас есть все родительские узлы с указанным процентом высоты с фиксированной высотой в пикселях, ems и т. д. на верхнем уровне. Таким образом, высота будет каскадно снижаться до вашего элемента.

Вы можете указать 100% для html и body элементов, как указано ранее @Travis, чтобы высота страницы каскадно доходила до ваших узлов.

Лайос Месарос
источник
9

После долгих поисков и попыток ничто не решило мою проблему, кроме

style = "height:100%;"

на детей Div

и для родителей применить это

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

Кроме того, я использую загрузчик, и это не повредило отзывчивый для меня.

Хакан Фистик
источник
1
Я должен был удалить, flex-direction: column;чтобы это работало на меня.
Ричард Хеджес
6

На основе метода, описанного в этой статье, я создал динамическое решение .Less:

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>

Меньше:

/* 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;
            }
        }
    }
}
Дмитрий Ефименко
источник
3

Я знаю, что прошло много времени с тех пор, как вопрос был задан, но я нашел простое решение и подумал, что кто-то может его использовать (извините за плохой английский). Здесь это идет:

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>

Простой пример Обратите внимание, что вы можете превратиться в отзывчивость.

Паула Флек
источник
О, я забыл: если вы хотите выровнять содержимое .sidebar по центру, просто измените "vertical-align: top" на "vertical-align: middle".
Паула Флек
2

Мое решение:

$(window).resize(function() {
   $('#div_to_occupy_the_rest').height(
        $(window).height() - $('#div_to_occupy_the_rest').offset().top
    );
});
Рафаэль Руис Муньос
источник
1

В названии вопроса и его содержании есть некоторое противоречие. Название говорит о родительском div, но вопрос заставляет это звучать так, как будто вы хотите, чтобы два родственных div (навигация и контент) были одинаковой высоты.

Вы (а) хотите, чтобы навигация и контент были на 100% выше основной, или (б) хотите, чтобы навигация и контент были одинаковой высоты?

Я буду считать (б) ... если это так, я не думаю, что вы сможете сделать это, учитывая вашу текущую структуру страницы (по крайней мере, не с чистым CSS и без сценариев). Вам, вероятно, нужно сделать что-то вроде:

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

и установите для содержимого div, чтобы было левое поле любой ширины навигационной панели. Таким образом, контент находится справа от навигации, и вы можете установить div навигации равным 100% высоты контента.

РЕДАКТИРОВАТЬ: я делаю это полностью в моей голове, но вам, вероятно, также необходимо установить левое поле навигационного элемента в отрицательное значение или установить его абсолютное левое значение на 0, чтобы переместить его обратно в крайнее левое положение. Проблема в том, что есть много способов сделать это, но не все они будут совместимы со всеми браузерами.

Пол Эбботт
источник
1

[Ссылаясь на код Less из Dmity в другом ответе] Я предполагаю, что это какой-то «псевдокод»?

Из того, что я понимаю, попробуйте использовать технику искусственных столбцов, которая должна сработать.

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

Надеюсь это поможет :)

jluna
источник
4
В зависимости от порядка сортировки ответов трудно сказать, что означает «это» ... Я предполагаю, что речь идет о коде Дмитрия. Таким образом, это замечание относится к комментарию под его ответом! И, к вашему сведению, это не псевдокод, это код на языке Less, способ определения CSS процедурным способом.
PhiLho
1

Этот трюк работает: добавление последнего элемента в ваш раздел HTML в стиле clear: both;

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

Все до этого будет включено в высоту.

user945389
источник
1

давать position: absolute;ребенку работали в моем случае

neoDev
источник
1

Вы используете 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>

Ини
источник
1

Этот ответ больше не идеален, так как CSS flexbox и grid были реализованы в CSS. Однако это все еще рабочее решение

На меньшем экране вы, вероятно, захотите сохранить высоту автоматически, так как col1, col2 и col3 накладываются друг на друга.

Однако после точки останова медиа-запроса вы бы хотели, чтобы столбцы отображались рядом друг с другом с одинаковой высотой для всех столбцов.

1125 пикселей - это только пример точки останова ширины окна, после которой вы хотите установить для всех столбцов одинаковую высоту.

<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>

Вы можете, конечно, установить больше точек останова, если вам нужно.

<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
источник
1

У меня была такая же проблема, она работала, основываясь на ответе Хакама Фостока, я создал небольшой пример, в некоторых случаях он мог бы работать без добавления display: flex;и flex-direction: column;в родительском контейнере.

.row {
    margin-top: 20px;
}

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

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

JSFiddle

Builo
источник
0

Как показано ранее, flexbox является самым простым. например.

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

это выровняет все дочерние элементы по центру в родительском элементе.

Чандан Пурохит
источник
3
это не отвечает на вопрос, они хотят равной высоты, не центрируя содержимое
Ryan M
0
.row-eq-height {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display:         flex;
 }

От:

http://getbootstrap.com.vn/examples/equal-height-columns/equal-height-columns.css

заявляет загрузчик, но вам не нужен загрузчик, чтобы использовать это. Отвечая на этот старый вопрос, как это работает для меня, и, кажется, довольно легко реализовать.

Это был тот же ответ, который я дал на этот вопрос

eaglei22
источник
0

Здесь старомодная демоверсия на основе position: absoluteконтейнера содержимого и position: relativeродительского контейнера.

Что касается современного способа сделать это - гибкие боксы являются лучшими.

WebBrother
источник
-3

Самый простой способ сделать это - просто подделать его. В течение нескольких лет этот список широко освещался, как в статье Дана Седерхолма от 2004 года .

Вот как я обычно это делаю:

<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>

Вы можете легко добавить заголовок к этому дизайну, обернув #container в другой div, вставив div заголовка в качестве родственного элемента # контейнера и перенеся стили полей и ширины в родительский контейнер. Кроме того, CSS должен быть перемещен в отдельный файл и не храниться в строке и т. Д. И т. Д. Наконец, класс clearfix может быть найден в positioniseverything .

Аарон Бреторст
источник