Ребенок внутри родителя с минимальной высотой: 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.