Сделать div (высота) занимающим оставшуюся высоту родителя

108

http://jsfiddle.net/S8g4E/

У меня есть контейнер divс двумя детьми. Первый ребенок имеет заданный рост. Как мне сделать так, чтобы второй дочерний divэлемент занимал «свободное место» контейнера, не задавая определенной высоты?

В этом примере розовый цвет divдолжен занимать также белое пространство.


Подобно этому вопросу: как заставить div занимать оставшуюся высоту?

Но я не хочу давать абсолютную позицию .

Альваро
источник
Я пробовал als дать высоту второго ребенка 100%, но не получилось: jsfiddle.net/S8g4E/1
Alvaro

Ответы:

156

Расширение #downдочернего элемента, чтобы заполнить оставшееся пространство, #containerможет быть выполнено различными способами в зависимости от поддержки браузера, которую вы хотите достичь, и от того, #upимеет ли она определенную высоту.

Образцы

Сетка

gridМакет CSS предлагает еще один вариант, хотя он может быть не таким простым, как модель Flexbox. Однако для этого требуется только стилизация элемента контейнера:

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

В grid-template-rows определяет первую строку как фиксированную высоту 100 пикселей, а оставшиеся строки автоматически растягиваются, чтобы заполнить оставшееся пространство.

Я почти уверен, что IE11 требует -ms-префиксов, поэтому не забудьте проверить функциональность в браузерах, которые вы хотите поддерживать.

Flexbox

Модульflexbox CSS3 Flexible Box Layout ( ) теперь хорошо поддерживается и его очень легко реализовать. Поскольку он гибкий, он работает даже тогда, когда #upне имеет определенной высоты.

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

Важно отметить, что поддержка IE10 и IE11 для некоторых свойств flexbox может содержать ошибки, а IE9 или более ранняя версия не поддерживает вообще.

Расчетная высота

Еще одно простое решение - использовать функциональный блок CSS3calc , как указывает Альваро в своем ответе , но для этого требуется, чтобы высота первого дочернего элемента была известным значением:

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

Он довольно широко поддерживается, с единственными заметными исключениями: <= IE8 или Safari 5 (без поддержки) и IE9 (частичная поддержка). Некоторые другие проблемы включают использование calc в сочетании с преобразованием или box-shadow , поэтому обязательно проверьте в нескольких браузерах, если это вас беспокоит.

Другие альтернативы

Если старше необходима поддержка, вы могли бы добавить height:100%;к#down сделают розовую Диву полную высоту, с одной оговоркой. Это вызовет переполнение контейнера, потому что #upтолкает его вниз.

Следовательно, вы можете добавить overflow: hidden; в контейнер, чтобы исправить это.

В качестве альтернативы, если высота #upфиксирована, вы можете расположить ее абсолютно внутри контейнера и добавить верхнюю обивку к#down .

И еще один вариант - использовать отображение таблицы:

#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
Я бы хотел, чтобы # внизу было # высота контейнера - # высота вверх. Так что скрытое переполнение - это не то, что я ищу. А также не хочу использовать абсолютную позицию. Спасибо!
Alvaro
@Alvaro, я добавил еще один вариант, используя табличные дисплеи. Минус здесь - совместимость. PS Элемент, расположенный абсолютно внутри контейнера, position: relative;позиционирует его относительно контейнера, а не окна. Так что это должен быть жизнеспособный вариант.
пользователь
2
Table-row должен работать на вас, см. Этот jsFiddle для доказательства. Абсолютный метод позиции не сможет дать те же результаты, что и эта скрипка, поэтому мы можем вычеркнуть это из списка (#down и #container будут иметь одинаковую высоту в этом сценарии).
пользователь
3
Ты многого просишь, @Alvaro. CSS - это не язык сценариев; он не может рассчитывать вещи. Вы застряли либо на иллюзиях, либо на js.
Jezen Thomas
1
@Quantastical, спасибо за вашу помощь, но в своем последнем редактировании вы просто скопировали ответ, который я опубликовал. По крайней мере, было бы неплохо упомянуть об этом.
Alvaro
24

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

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

Вот css

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

И подробнее об этом здесь: http://css-tricks.com/a-couple-of-use-cases-for-calc/

Поддержка браузера: http://caniuse.com/#feat=calc

Альваро
источник
1
Я тоже использовал CSS3, calcгде широкая поддержка браузеров не так важна (IE8 и ниже и Safari 5 не поддерживают его).
user
3
Есть ли способ сделать то же самое с динамической #upвысотой?
Адам Уэйт
@AdamWaite с динамической высотой #up вы захотите использовать решение переполнения, описанное в другом ответе.
пользователь
5

В моем ответе используется только CSS, и он не использует overflow: hidden или display: table-row. Это требует, чтобы у первого ребенка действительно была заданная высота, но в своем вопросе вы указываете, что только второй ребенок должен иметь не указанную высоту, поэтому я считаю, что вы должны найти это приемлемым.

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/

TWR Коул
источник
3

Аннотация

Я не нашел полностью удовлетворительного ответа, поэтому мне пришлось выяснить его сам.

Мои требования:

  • элемент должен принимать ровно оставшееся пространство , либо когда его содержание размер является меньше или больше , чем оставшийся размер пространства (во втором случае скроллбара должны быть показаны );
  • решение должно работать, когда родительская высота вычислена , а не указана ;
  • calc()не должен использоваться, так как оставшийся элемент не должен ничего знать о размерах других элементов;
  • Следует использовать современную и знакомую технику верстки, такую ​​как гибкие боксы .

Решение

  • Превратите во флексбоксы всех прямых родителей с вычисленной высотой (если есть) и следующего родителя, высота которого указана ;
  • Укажите flex-grow: 1для всех прямых родителей с вычисленной высоты (если таковые имеются) и элемент , таким образом они будут занимать все оставшееся пространство , когда размер содержание элемента меньше;
  • Укажите flex-shrink: 0для всех гибких элементов фиксированную высоту, чтобы они не становились меньше, когда размер содержимого элемента больше, чем размер оставшегося пространства;
  • Укажите overflow: hiddenдля всех прямых родителей с вычисленной высоты (если таковые имеются) , чтобы отключить скроллинг и запретить отображение содержимого переполнения;
  • Указание overflow: autoна элемент , чтобы включить прокрутку внутри него.

JSFiddle (элемент имеет прямых родителей с вычисленной высотой)

JSFiddle (простой случай: нет прямых родителей с вычисленной высотой)

Н. Кудрявцев
источник
2

проверьте демо - http://jsfiddle.net/S8g4E/6/

использовать css -

#container { width: 300px; height: 300px; border:1px solid red; display: table;}
#up { background: green; display: table-row; }
#down { background:pink; display: table-row;}
Дипак
источник
Вы должны добавить height: 1pxк, #upчтобы убедиться, что он занимает минимальную высоту. Вот поддержка браузером для display: table: caniuse.com/css-table
30dot
Не могли бы вы показать мне, как можно достичь этого решения в этом "более сложном" примере, пожалуйста: jsfiddle.net/fyNX4 Большое спасибо
Альваро
2

Если меня не недоразумение, вы можете просто добавить height: 100%;и overflow:hidden;к #down.

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

Живая ДЕМО

Изменить: поскольку вы не хотите использовать overflow:hidden;, вы можете использовать display: table;для этого сценария; однако он не поддерживается до IE 8. ( display: table;поддержка )

#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;
}​

Живая ДЕМО

Примечание: вы сказали, что хотите, чтобы #downвысота была равна #containerвысоте минус #upвысота. display:table;Решение делает именно то, что и это jsfiddle будет изображать , что довольно ясно.

Джош Майн
источник
1
Я не хочу, чтобы #down превышало # высоту контейнера
Альваро,
Я только что это заметил. Вы можете добавить, overflow:hiddenчтобы скрыть дополнительный контент.
Josh Mein
1
Я скопирую / вставлю то, что я сказал MrSlayer: я бы хотел, чтобы #down было #container height - #up height. Так что скрытое переполнение - это не то, что я ищу. А также не хочу использовать абсолютную позицию. Спасибо!
Альваро
Проблема в том, что если вы вернете два div в своем примере, зеленый div окажется снаружи.
Ced
Это вообще не отвечает на вопрос. Он гласит: «Занять всю оставшуюся высоту», даже если он занимает всю оставшуюся высоту, произойдет переполнение.
Гиридхар Карник,
1

Вы можете использовать поплавки для перемещения содержимого вниз:

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

У вас есть контейнер фиксированного размера:

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

Контенту разрешено течь рядом с поплавком. Если мы не установим float на полную ширину:

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

В то время как #upи #downразделяют верхнюю позицию, #downсодержимое может начинаться только после нижней части плавающего #up:

#down {
    height:100%;
}​
бизиклоп
источник
Обратите внимание, что на #upсамом деле это верхняя часть #down: jsfiddle.net/thirtydot/S8g4E/9
30dot
Да, вот как это работает. Но если OP не нужна закругленная граница или что-то еще #up, то это, вероятно, приемлемо.
biziclop
Это решение близко, но я бы хотел, чтобы #down было #container height - #up height. (В вашем решении # высота вниз = # высота контейнера). Спасибо '
Альваро
1
@Alvaro: Почему это должно быть так? Такое решение в большинстве случаев выглядит правильным, даже если это всего лишь иллюзия.
30dot
Что ж, этот вопрос представляет собой упрощенный пример из более «сложного» примера: jsfiddle.net/fyNX4 Не сработает, не так ли?
Alvaro
-3

Я не уверен, что это можно сделать исключительно с помощью CSS, если только вам не удобно имитировать это с помощью иллюзий. Возможно использовать ответ Джош Mein, и набор #containerдляoverflow:hidden .

Для чего это стоит, вот решение jQuery:

var contH = $('#container').height(),
upH = $('#up').height();
$('#down').css('height' , contH - upH);
Джезен Томас
источник
Спасибо, я искал решение на чистом Css.
Alvaro