Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
153 lines (103 sloc) 6.32 KB

Особенности свойства "height" в %

Обычно свойство height, указанное в процентах, означает высоту относительно внешнего блока.

Однако, всё не так просто. Интересно, что для произвольного блочного элемента height в процентах работать не будет!

Чтобы лучше понимать ситуацию, рассмотрим пример.

Пример

Наша цель -- получить вёрстку такого вида:

[iframe src="height-percent" height=160 link edit]

При этом блок с левой стрелкой должен быть отдельным элементом внутри контейнера.

Это удобно для интеграции с 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;
}

А теперь -- посмотрим этот вариант в действии:

[iframe src="height-percent-float" height=160 link edit]

Как видно, блок со стрелкой вообще исчез! Куда же он подевался?

Ответ нам даст спецификация 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 в % внутри будет работать */
}

Результат:

[iframe src="height-percent-float-exact" height="230" link edit]

...Но в данном случае этот путь неприемлем! Ведь мы не знаем, сколько будет текста и какой будет итоговая высота.

Поэтому решим задачу по-другому.

Правильно: 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;
}

Результат:

[iframe src="height-percent" height=160 link edit]

Проблема с 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;