Обычно свойство height
, указанное в процентах, означает высоту относительно внешнего блока.
Однако, всё не так просто. Интересно, что для произвольного блочного элемента height
в процентах работать не будет!
Чтобы лучше понимать ситуацию, рассмотрим пример.
Пример
Наша цель – получить вёрстку такого вида:
При этом блок с левой стрелкой должен быть отдельным элементом внутри контейнера.
Это удобно для интеграции с JavaScript, чтобы отлавливать на нём клики мыши.
То есть, HTML-код требуется такой:
<div class="container">
<div class="toggler">
<!-- стрелка влево при помощи CSS, ширина фиксирована -->
</div>
<div class="content">
...Текст...
</div>
</div>
Как это реализовать? Подумайте перед тем, как читать дальше…
Придумали?.. Если да – продолжаем.
Есть разные варианты, но, возможно, вы решили сдвинуть .toggler
влево, при помощи float:left
(тем более что он фиксированной ширины) и увеличить до height: 100%
, чтобы он занял всё пространство по вертикали.
Вы ещё не видите подвох? Смотрим внимательно, что будет происходить с height: 100%
…
Демо height:100% + float:left
CSS:
.container {
border: 1px solid black;
}
.content {
/* margin-left нужен, так как слева от содержимого будет стрелка */
margin-left: 35px;
}
.toggler {
/* Зададим размеры блока со стрелкой */
height: 100%;
width: 30px;
float: left;
background: #EEE url("arrow_left.png") center center no-repeat;
border-right: #AAA 1px solid;
cursor: pointer;
}
А теперь – посмотрим этот вариант в действии:
Как видно, блок со стрелкой вообще исчез! Куда же он подевался?
Ответ нам даст спецификация CSS 2.1 пункт 10.5.
«Если высота внешнего блока вычисляется по содержимому, то высота в % не работает, и заменяется на height:auto
. Кроме случая, когда у элемента стоит position:absolute
.»
В нашем случае высота .container
как раз определяется по содержимому, поэтому для .toggler
проценты не действуют, а размер вычисляется как при height:auto
.
Какая же она – эта автоматическая высота? Вспоминаем, что обычно размеры float
определяются по содержимому (10.3.5). А содержимого-то в .toggler
нет, так что высота нулевая. Поэтому этот блок и не виден.
Если бы мы точно знали высоту внешнего блока и добавили её в CSS – это решило бы проблему.
Например:
/*+ no-beautify */
.container {
height: 200px; /* теперь height в % внутри будет работать */
}
Результат:
…Но в данном случае этот путь неприемлем! Ведь мы не знаем, сколько будет текста и какой будет итоговая высота.
Поэтому решим задачу по-другому.
Правильно: height:100% + position:absolute
Проценты будут работать, если поставить .toggler
свойство position: absolute
и спозиционировать его в левом-верхнем углу .container
(у которого сделать position:relative
):
.container {
position: relative;
border: 1px solid black;
}
.content {
margin-left: 35px;
}
.toggler {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 30px;
cursor: pointer;
border-right: #AAA 1px solid;
background: #EEE url("arrow_left.png") center center no-repeat;
}
Результат:
Проблема с height: 100%, проявляющаяся, когда у родительского элемента не установлен height, но указан min-height
Вам необходимо установить height: 1px для родителя, чтобы дочерний элемент смог занять всю высоту указанную в min-height.
.parent {
min-height: 300px;
height: 1px; /* Требуется, чтобы дочерний блок взял высоту 100% */
}
.child {
height: 100%;
}
Итого
- Свойство
height
, указанное в %, работает только если для внешнего блока указана высота. - Стандарт CSS 2.1 предоставляет обход этой проблемы, отдельно указывая, что проценты работают при
position:absolute
. На практике это часто выручает. - Если у родительского элемента не установлено height, а указано min-height, то, чтобы дочерний блок занял 100% высоты, нужно родителю поставить свойство height: 1px;