Как сделать floated div на 100% высоты его родителя?

256

Вот HTML-код:

<div id="outer">
    <div id="inner"></div>
    Test
</div>

А вот и CSS:

#inner {
  float: left;
  height: 100%;
}

После проверки с помощью инструментов разработчика Chrome внутренний div получает высоту 0px.

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

Натан Осман
источник
1
Итак, вы хотите, чтобы текст во внешнем div (а не во внутреннем div), но плавающий внутренний div был высотой внешнего div?
edl
Какого конечного результата вы пытаетесь достичь? Я предполагаю, что мое заблуждение заключается в том, что если внутренний div такой же высокий, как внешний, а внешний такой же высокий, как текст, разве это не то же самое, что иметь текст во внутреннем div?
EDL
2
@edl: Да, это так :). Причина, по которой я так хочу, заключается в том, что внутренний div имеет изображение в качестве фона. Текст должен быть рядом с ним. Оба должны быть внутри внешнего элемента div, поскольку у него тоже есть фоновое изображение.
Натан Осман
3
Также см. Stackoverflow.com/questions/1122381
Чедвик
2
Видеть и пробовать ответы на этот вопрос было просто удручающе.
EternalHour

Ответы:

125

Чтобы #outerвысота основывалась на его содержимом и #innerосновывалась на его высоте, сделайте оба элемента абсолютно позиционированными.

Больше подробностей можно найти в спецификации для свойства css height , но, по сути, #innerдолжно игнорировать #outerвысоту, если есть #outerвысота auto, если только #outer она не расположена абсолютно. Тогда #innerвысота будет равна 0, если только #inner сама не позиционируется абсолютно.

<style>
    #outer {
        position:absolute; 
        height:auto; width:200px; 
        border: 1px solid red; 
    }
    #inner {
        position:absolute; 
        height:100%; 
        width:20px; 
        border: 1px solid black; 
    }
</style>

<div id='outer'>
    <div id='inner'>
    </div>
    text
</div>

Однако ... При позиционировании #innerабсолютно floatнастройка будет игнорироваться, поэтому вам нужно будет #innerявно указать ширину и добавить отступы, #outerчтобы имитировать перенос текста, я подозреваю, что вы хотите. Например, ниже, отступом #outerявляется ширина #inner+3. Удобно (так как весь смысл был в том, чтобы получить #innerвысоту до 100%), нет необходимости переносить текст внизу #inner, так что это будет выглядеть так же, как #innerи плавание.

<style>
    #outer2{
        padding-left: 23px;
        position:absolute; 
        height:auto; 
        width:200px; 
        border: 1px solid red; 
    }
    #inner2{
        left:0;
        position:absolute; 
        height:100%; 
        width:20px; 
        border: 1px solid black; 
   }
</style>

<div id='outer2'>
    <div id='inner2'>
    </div>
    text
</div>

Я удалил свой предыдущий ответ, так как он основывался на слишком многих неверных предположениях о вашей цели.

Чедвик
источник
118
Хм .. вопрос был о Floated div's. Вы ответили об абсолютной позиции divs
Михкель Л.
57
Я никогда не перестаю удивляться, насколько сложно достичь безумно простых вещей HTML/CSS:)
Юрий Наконечный
15
Любой способ сделать это без жесткой ширины? Не подходит для отзывчивых контейнеров.
Джейк Уилсон
23
Я не знаю, почему это так принято и было отклонено. Вопрос о плавающих элементах div, что и привело меня сюда из моих поисков, и вместо этого он отвечает на абсолютно позиционированные элементы div.
Мэтт К
2
Как сделать плавающий контейнер вертикально подходящим для своего контейнера? Не заставляя его больше плавать! Ха - ха. Хорошая попытка, и достаточно близко, чтобы считаться полезной, на самом деле.
Рольф
124

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

display: flex;

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

Редактировать: Единственным недостатком является IE, как обычно, IE9 не поддерживает flex. http://caniuse.com/flexbox

Редактировать 2: Как отметил @toddsby, выровнять элементы для родителя, и его значение по умолчанию на самом деле растянуть . Если вы хотите другое значение для дочернего, есть свойство align-self.

Изменить 3: jsFiddle: https://jsfiddle.net/bv71tms5/2/

Aiphee
источник
3
Следует отметить, что это работает только в современных браузерах, и даже тогда требует префиксов поставщиков.
Контур
12
Я удивлен, что этому решению не было уделено больше внимания, учитывая, что исходный вопрос требует, чтобы дочерний элемент div находился в плавающем положении, и все позиции: абсолютные решения действительно дают гаечный ключ в работах в большинстве ситуаций, где вы будете использовать float. Это решение предоставляет отличное решение, где побочные эффекты позиции: абсолютные не являются проблемой, и если вы хотите копнуть немного дальше, можно получить довольно хорошую кросс-браузерную совместимость.
Лука
Это ответ прямо здесь. IE9 выйдет достаточно скоро, может также помочь ему, сделав хороший, солидный удар. Это решение очень хорошее, простое и легкое ... Я закончил, взламывая альтернативные решения. ;)
jrista
2
В соответствии с самой последней спецификацией для Flexbox: см. W3.org/TR/css-flexbox-1/#align-items-property . align-items: stretch;не требуется, так как это значение по умолчанию. Также это должно быть определено по родителю, а не по ребенку.
17
1
Добавлена ​​скрипка в ответе. @Tigran
Aiphee
77

На самом деле, пока родительский элемент расположен, вы можете установить высоту дочернего элемента на 100%. А именно, если вы не хотите, чтобы родитель был абсолютно позиционирован. Позвольте мне объяснить далее:

<style>
    #outer2 {
        padding-left: 23px;
        position: relative; 
        height:auto; 
        width:200px; 
        border: 1px solid red; 
    }
    #inner2 {
        left:0;
        position:absolute; 
        height:100%; 
        width:20px; 
        border: 1px solid black; 
    }
</style>

<div id='outer2'>
    <div id='inner2'>
    </div>
</div>
Натаниэль Швайнберг
источник
14
Круто, это менее ограничивает, чем требование Чедвика position:absolute(которое может повлиять на стили сайта)
Генри
3
Это может быть только я, но у меня есть проблемы, если боковая панель больше, чем содержание. Цвет фона остановится на родительском контейнере, но содержимое боковой панели будет переполнено за пределами родительского контейнера.
Howdy_McGee
Это гораздо более гибкое решение, и даже если у вас есть несколько всплывающих дочерних элементов, кажется приемлемым недостатком стилизовать их абсолютно смещенное смещение. +1
контур
Спасибо очень много. Я опубликовал свое конкретное решение в качестве ответа на другой вопрос на SO: stackoverflow.com/a/31749164/84661 .
Брайан Хаак
24

Пока вам не нужно поддерживать версии Internet Explorer более ранние, чем IE8, вы можете использовать display: table-cellдля этого:

HTML:

<div class="outer">
    <div class="inner">
        <p>Menu or Whatever</p>
    </div>
    <div class="inner">
        <p>Page contents...</p>
    </div>
</div>

CSS:

.inner {
    display: table-cell;
}

Это заставит каждый элемент с .innerклассом занимать полную высоту своего родительского элемента.

Натан Осман
источник
Хотя это будет работать, оно не будет показывать поле, даже если вы его укажете. Так что это решение не удастся, если вы хотите назначить маржу. Вы можете назначить отступы как обходной путь, но как бы вы решили это, если бы вам потребовалось поле (а не отступы)?
Devner
13
Я что-то здесь упускаю? Ваш вопрос требует, чтобы плавающий элемент имел высоту 100%. При перемещении display: table-cell;элемент больше не заполняет высоту своего контейнера? Должно быть, я что-то упустил, потому что это твой собственный вопрос ...?
user56reinstatemonica8
16

Я сделал пример, решающий твою проблему.

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

HTML

<div class="container">
    <div class="left">"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." </div>
  <div class="right-wrapper">
    <div class="right">"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." </div>
  </div>
  <div class="clear">&nbsp;</div>
</div>

CSS:

.container {
    width: 100%;
    position:relative;
}
.left {
    width: 50%;
    background-color: rgba(0, 0, 255, 0.6);
    float: left;
}
.right-wrapper {
    width: 48%;
    float: left;
}
.right {
    height: 100%;
    position: absolute;
}

Пояснение: .right div абсолютно позиционирован. Это означает, что его ширина и высота, а также верхняя и левая позиции будут рассчитываться на основе ТОЛЬКО или относительного положения первого родительского элемента div, если свойства ширины или высоты явно объявлены в CSS; если они не объявлены явно, эти свойства будут вычислены на основе родительского контейнера (.right-wrapper).

Таким образом, высота 100% DIV будет рассчитываться на основе конечной высоты .container, а окончательная позиция .right будет рассчитываться на основе родительского контейнера.

Mandarinazul
источник
1
Это надежное решение для ситуаций, когда вы можете гарантировать, что .rightсодержимое столбца короче .leftсодержимого столбца. Например, если вы используете это для компонента, в котором .leftстолбец имеет некоторое содержимое переменного размера, а в правом столбце просто отображается стрелка на странице сведений, это решение работает хорошо. +1 за это
Захари Кнебель
15

Вот более простой способ добиться этого:

  1. Установите отображение контейнера трех элементов (#outer): таблица
  2. И установить сами элементы (#inner) отображения: table-cell
  3. Убери плавающий.
  4. Успех.
#outer{
    display: table;
}
#inner {
    display: table-cell;
    float: none;
}

Благодаря @Itay в Floated div, 100% высоты

leopinzon
источник
8

Если вы готовы использовать немного jQuery, ответ прост!

$(function() {
    $('.parent').find('.child').css('height', $('.parent').innerHeight());
});

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

Надеюсь, это поможет другим фанатам jQuery.

Оби-Дан
источник
18
Кажется излишним бросать javascript в этой проблеме с макетом.
Контур
1
Как тот, кто должен развиваться в IE: СПАСИБО!
Ладья
1
Может быть, немного излишним, но это прекрасный ответ, спасибо!
Мартин
1
Я согласен, что все проблемы позиционирования должны решаться без JS.
michaeluskov
1
Использовать JS и jQuery
излишне
3

Это пример кода для системы сетки с равной высотой.

#outer{
width: 100%;
margin-top: 1rem;
display: flex;
height:auto;
}

Выше CSS для внешнего div

#inner{
width: 20%;
float: left;
border: 1px solid;
}

Выше внутренний див

Надеюсь, это поможет вам

Biswajit
источник
1

Это помогло мне.

#outer {
    position:relative;
}
#inner {
    position:absolute;
    top:0;
    left:0px;
    right:0px;
    height:100%;
}

Измените право: и слева: установить предпочтительную # внутреннюю ширину.

Sevenkey
источник
1

Аналогичный случай, когда вам нужно, чтобы несколько дочерних элементов имели одинаковую высоту, может быть решен с помощью flexbox:

https://css-tricks.com/using-flexbox/

Установите display: flex;для родительских и flex: 1;дочерних элементов, они все будут иметь одинаковую высоту.

romaroma
источник
-1

пытаться

#outer{overflow: auto;}

показать больше параметров в: Как вы удерживаете родителей всплывающих элементов от разрушения?

Родриго Баррейру
источник
опция «переполнение: скрытый», кажется, работает лучше, потому что нет шансов перекатиться ...
Родриго Баррейру
Если вы нашли лучшее решение, вы можете отредактировать свой ответ. Также было бы хорошо, если бы вы добавили больше информации в свой ответ, например, информацию, представленную в ссылке.
Дональд Дак