Ребенок внутри родителя с минимальной высотой: 100% не наследует рост


167

Я нашел способ заставить контейнер div занимать хотя бы полную высоту страницы, установив min-height: 100%;. Однако, когда я добавляю вложенный div и set height: 100%;, он не растягивается до высоты контейнера. Есть ли способ это исправить?

html, body {
  height: 100%;
  margin: 0;
}

#containment {
  min-height: 100%;
  background: pink;
}

#containment-shadow-left {
  height: 100%;
  background: aqua;
}
<div id="containment">
  <div id="containment-shadow-left">
    Hello World!
  </div>
</div>


27
Современный день решение: дать контейнер display:flexи flex-direction:columnи дать ребенку flex:1.
Jackocnr

3
@jackocnr Это не работает ни в одном IE из-за ошибки , это было исправлено в Edge.
Наклейки

Ответы:


146

Это сообщенная ошибка веб-набора (chrome / safari), дети родителей с минимальной высотой не могут наследовать свойство высоты: https://bugs.webkit.org/show_bug.cgi?id=26559

Очевидно, что Firefox тоже затронут (в данный момент не могу протестировать в IE)

Возможное решение:

  • добавить позицию: относительно #containment
  • позиция добавления: абсолютная к # сдерживающая тень-левая

Ошибка не показывает, когда внутренний элемент имеет абсолютное позиционирование.

Смотрите http://jsfiddle.net/xrebB/

Изменить 10 апреля 2014 г.

Поскольку в настоящее время я работаю над проектом, для которого мне действительно нужны родительские контейнеры min-heightи дочерние элементы, наследующие высоту контейнера, я провел еще несколько исследований.

Первое: я больше не уверен, является ли текущее поведение браузера ошибкой. Спецификации CSS2.1 говорят:

Процент рассчитывается относительно высоты содержащего блока сгенерированного блока. Если высота содержащего блока не указана явно (то есть зависит от высоты содержимого), и этот элемент не является абсолютно позиционированным, значение вычисляется как 'auto'.

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

Во-вторых, я нашел обходной путь:

Если я установлю свой элемент контейнера display:tableс height:inheritним, он будет действовать точно так же, как если бы я дал ему min-height100%. И - что более важно - если я установлю дочерний элемент, display:table-cellон будет отлично наследовать высоту элемента контейнера - будь то 100% или более.

Полный CSS:

html, body {
  height: 100%;
  margin: 0;
}

#container {
  background: green;
  display: table;
  height: inherit;
  width: 100%;
}

#content {
  background: red;
  display: table-cell;
}

Разметка:

<div id="container">
  <div id="content">
      <p>content</p>
  </div>
</div>

См. Http://jsfiddle.net/xrebB/54/ .


27
Чувак, это еще не исправлено: S
Mārtirš Briedis

Да, это не так - я вижу, что есть несколько патчей, но в Chrome 29 он все еще не отображает ожидаемое поведение. Однако он не работает в Firefox 23, IE 10, Safari 5 или Opera 12. По крайней мере, все браузеры согласны ...
Paul d'Aoust

3
Странное чтение спецификации заключить, что min / max-height не является явным ... и под странным я имею в виду неправильно. Читая весь абзац, в контексте эта интерпретация неверна. Чтобы выяснить, почему «высота содержащего блока» в контексте семантически отличается от свойства height. Если вместо этого формулировка будет « свойством высоты содержащего блока», тогда Ваша интерпретация будет иметь смысл (и будет ошибкой в ​​спецификации).
WraithKenny

1
Это 2019. Мы пропустили 10-летний юбилей этой ошибки. Гибкое решение сработало для меня stackoverflow.com/questions/8468066/…
Илья Чернов

6
Я из эпохи блокировки
Дэвид Калланан

174

Добавить height: 1pxв родительский контейнер. Работает в Chrome, FF, Safari.


8
Это не решает проблему, фактически вы переопределяете настройку min-height: 100%, которая не дает ничего, чего нельзя достичь с высотой: 100%, чего не хочет OP
styler

16
Добавление @styler height: 1px;не отменяет минимальную высоту. Наоборот. Это лучшее решение здесь ... демо: jsbin.com/mosaboyo/1/edit
jjenzz

2
Узнайте, почему height: 1px;работает stackoverflow.com/questions/2341821/height100-vs-min-height100
Бен Алави,

31
@jjenzz Проблема с этим, к которой, как мне кажется, пытался стайлер, заключается в том, что она не сохраняет черту расширения min-height. Например, если текста достаточно, он переполнится. См. Jsbin.com/vuyapitizo/1
binaryfunt

3
Цитирую комментарий Павла ниже: «Но он не позволяет контейнеру расти, что отрицательно сказывается на использовании минимальной высоты». stackoverflow.com/questions/8468066/…
Лео Лей

103

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

РЕШЕНИЕ :min-height: inherit;

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

.parent {
  min-height: 300px;
  background-color: rgba(255,255,0,0.5); //yellow
}

.child {
  min-height: inherit;
  background-color: rgba(0,255,0,0.5); //blue
}

p {
  padding: 20px;
  color: red;
  font-family: sans-serif;
  font-weight: bold;
  text-align: center;
}
<div class="parent">
  <div class="child">
    <p>Yellow + Blue = Green :)</p>
  </div>
</div>

Таким образом, ребенок теперь действует как высота 100% от минимальной высоты.

Я надеюсь, что некоторые люди находят это полезным :)


9
Частично работает, но ребенок только наследует min-height. Когда рост родителей больше, ребенок не будет расширяться.
OguzGelal

1
Вы спасли мою жизнь
Casamia

6
Это работает только тогда, когда минимальная высота является абсолютной, а не процентной, AFAICS.
Бенджамин

4
Работает также хорошо, если родитель имеет значение VH! СПАСИБО!
user1658080

1
Не подходит для любой ситуации, но иногда очень помогает. Спасибо!
Blackbam

15

Это было добавлено в комментарии @jackocnr, но я пропустил это. Для современных браузеров я думаю, что это лучший подход.

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

#containment {
  min-height: 100%;
  display: flex;
  flex-direction: column;
}

#containment-shadow-left {
  flex: 1;
}

1
это лучшее, так как flexbox широко совместим.
Хосе Карлос Рамирес Васкес

8

Решение Kushagra Gour работает (по крайней мере, в Chrome и IE) и решает исходную проблему без использования display: table;и display: table-cell;. Смотрите плункер: http://plnkr.co/edit/ULEgY1FDCsk8yiRTfOWU

Установка min-height: 100%; height: 1px;на внешнем элементе делит его фактическую высоту, по крайней мере, 100%, как требуется. Это также позволяет внутреннему div правильно наследовать высоту.


23
Но он не позволяет контейнеру расти, что отрицательно сказывается на использовании минимальной высоты.
Сал

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

6

В дополнение к существующим ответам есть также единицы просмотра vh. Простой фрагмент ниже. Конечно, это может использоваться вместе с calc(), например, min-height: calc(100vh - 200px);когда верхний и нижний колонтитулы страницы имеют 200pxвысоту вместе.

body {
  margin: 0;
}

.child {
  min-height: 100vh;
  background: pink;
}
<div class="parent">
  <div class="child"></div>
</div>


3

Я не верю, что это ошибка в браузерах. Все ведут себя одинаково - то есть, как только вы перестанете указывать явную высоту, минимальная высота по сути является «последним шагом».

Похоже, это именно то, что предлагает спецификация CSS 2.1: http://www.w3.org/TR/CSS2/visudet.html#the-height-property

Процент рассчитывается относительно высоты содержащего блока сгенерированного блока. Если высота содержащего блока не указана явно (то есть зависит от высоты содержимого), и этот элемент не является абсолютно позиционированным, значение вычисляется как 'auto'.

Следовательно, поскольку min-heightродительский heightобъект не имеет явного набора свойств, по умолчанию используется значение auto.

Есть несколько способов обойти это, возможно, используя display: table-cellили более новые стили, такие как flexbox, если это возможно для браузеров вашей целевой аудитории. Вы можете также ниспровергать это в определенных ситуациях, используя topи bottomсвойство на абсолютно позиционированный внутренний элемент, который дает вам высоту 100% без указания так.


3

Хотя display: flex;было предложено здесь, рассмотрите возможность использования display: grid;сейчас, поскольку он широко поддерживается . По умолчанию единственный дочерний элемент сетки будет полностью заполнять своего родителя.

html, body {
  height: 100%;
  margin: 0;
  padding: 0; /* Don't forget Safari */
}

#containment {
  display: grid;
  min-height: 100%;
  background: pink;
}

#containment-shadow-left {
  background: aqua;
}


2

Для гуглеров:

Этот обходной путь jquery заставляет #containment автоматически получать высоту (by, height: auto), а затем получает фактическую высоту, назначенную в виде значения в пикселях.

<script type="text/javascript">
<!--
    $(function () {

        // workaround for webkit-bug http://stackoverflow.com/a/8468131/348841

        var rz = function () {
            $('#containment')
            .css('height', 'auto')
            .css('height', $('#containment').height() + 'px');
        };

        $(window).resize(function () {
            rz();
        });

        rz();

    })
-->
</script>

Хороший обходной путь, вы можете просто установить минимальную высоту элемента, не устанавливая высоту на «авто». Это сработало для меня.
Сальваторе Заппала

2

Лучший способ достигнуть этого в настоящее время состоит в том, чтобы использовать display: flex;. Однако вы можете столкнуться с проблемой при попытке поддержки IE11. Согласно https://caniuse.com с использованием flexbox:

IE 11 неправильно выравнивает элементы по вертикали при использовании min-height

Internet Explorer совместимое решение

Решение заключается в использовании display: table;на родителя и display: table-row;на ребенка как с height: 100%;заменой min-height: 100%;.

Большая часть решений , перечисленных здесь используют display: table, table-rowи / или table-cell, но они не копируют такое же поведение , как min-height: 100%;, что:

  • Наследовать вычисленную высоту родителя (в отличие от наследования его heightсвойства);
  • Позвольте высоте родителя превышать его min-height;

При использовании этого решения поведение остается тем же, и свойство min-heightне требуется, что позволяет обойти ошибку.

объяснение

Причина, по которой это работает, заключается в том, что, в отличие от большинства элементов, элементы используют display: tableи table-rowвсегда будут такими же высокими, как и их содержимое. Это заставляет их heightсвойство вести себя аналогично min-height.

Решение в действии

html, body {
  height: 100px;
  margin: 0;
}

#containment {
  display: table;
  height: 100%;
  background: pink;
  width: 100%;
}

#containment-shadow-left {
  display: table-row;
  height: 100%;
  background: aqua;
}

#content {
  padding: 15px;
}

#demo {
  display: none;
  background-color: red;
  height: 200px;
}

#demo-checkbox:checked ~ #demo {
  display: block;
}
<div id="containment">
  <div id="containment-shadow-left">
    <div id="content">
      <input id="demo-checkbox" type="checkbox">
      <label for="demo-checkbox">Click here for overflow demo</label>
      <div id="demo">This is taller than #containment</div>
    </div>
  </div>
</div>


1

Другое решение JS, которое является простым и может использоваться, чтобы избежать непростого решения только для CSS или дополнительной разметки / хакерства.

function minHeight(elm, percent) {
  var windowHeight = isNaN(window.innerHeight) ? 
                     window.clientHeight : window.innerHeight;
  var height = windowHeight * percent / 100;
  elm.style.minHeight = height + 'px';
}

W / JQuery:

function minHeight($elm, percent) {
  var windowHeight = $(window).height();
  var height = windowHeight * percent / 100;
  $elm.css('min-height', height + 'px');
}

Угловая директива:

myModule.directive('minHeight', ['$window', function($window) {
  return {
    restrict: 'A',
    link: function(scope, elm, attrs) {
      var windowHeight = isNaN($window.innerHeight) ? 
               $window.clientHeight : $window.innerHeight;
      var height = windowHeight * attrs.minHeight / 100;
      elm.css('min-height', height + 'px');
    }
  };
}]);

Быть использованным так:

<div>
  <!-- height auto here -->
  <div min-height="100">
    <!-- This guy is at least 100% of window height but grows if needed -->
  </div>
</div>

Спасибо за директивное решение. Это то, что я использовал, но не хотел, чтобы высота окна была минимальной; скорее я хотел унаследовать минимальную высоту родительского элемента, поэтому я изменил код так: var height = elm.parent () [0] .offsetHeight;
Сал

1

Это обычно работает для меня:


.parent {
  min-height: 100px;
  background-color: green;
  display: flex;
}
.child {
  height: inherit;
  width: 100%;
  background-color: red;
}
<!DOCTYPE html>
<html>
  <body>
    <div class="parent">
      <div class="child">
      </div>
    </div>
  </body>
</html>

0

Просто держать эту тему полно, я нашел решение не исследовал здесь , используя фиксированное положение.

Без переполнения

html, body, .wrapper, .parent, .child {
  position: fixed;
  top: 0; 
  bottom: 0;
  left: 0;
  right: 0;
  margin: 0;
  padding: 0;
  height: 100%;
}

.child {
  overflow: auto;
  background: gray;
}

.height-50 {
  height: 50%;
  width: 5em;
  margin: 10px auto;
  background: cyan;
}
<div class="wrapper">
  <div class="parent">
    <div class="child">
      
      <div class="height-50"></div>
      
    </div>
  </div>
</div>

С переполнением

html, body, .wrapper, .parent, .child {
  position: fixed;
  top: 0; 
  bottom: 0;
  left: 0;
  right: 0;
  margin: 0;
  padding: 0;
  height: 100%;
}

.child {
  overflow: auto;
  background: gray;
}

.height-150 {
  height: 150%;
  width: 5em;
  margin: 10px auto;
  background: cyan;
}
<div class="wrapper">
  <div class="parent">
    <div class="child">
      
      <div class="height-150"></div>
      
    </div>
  </div>
</div>


-2

Это то, что работает для меня с ростом в процентах и ​​ростом родителей в зависимости от роста детей. Прекрасно работает в Firefox, Chrome и Safari.

.parent {
  position: relative;
  min-height: 100%;
}

.child {
  min-height: 100vh;
}
<div class="parent">
    <div class="child"></div>
  </div>


-3

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

display:inline-block

Обновить

Это не работает. решение состоит в том, чтобы получить смещение родительского узла и использовать его на странице и с javascript.

<script>
    SomedivElement = document.getElementById('mydiv');
    SomedivElement.style.height = String(nvleft.parentNode.offsetHeight) + 'px';    
</script>
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.