CSS - почему не работает процентная высота?

Как получается процентное значение для height не работает, но процентное значение для width делает?

Например:

<div id="working"></div>
<div id="not-working"></div>
#working{
    width:80%;
    height:140px;
    background:orange;
}
#not-working{
    width:80%;
    height:30%;
    background:green;
}

Ширина #working в конечном итоге составляет 80% от области просмотра, но высота #not-working заканчивается тем, что 0.

6 ответов

Решение

Высота элемента блока по умолчанию равна высоте содержимого блока. Итак, учитывая что-то вроде этого:

<div id="outer">
    <div id="inner">
        <p>Where is pancakes house?</p>
    </div>
</div>

#inner станет достаточно высоким, чтобы вместить абзац и #outer вырастет достаточно высоким, чтобы вместить #inner,

Когда вы указываете высоту или ширину в процентах, это процент по отношению к родительскому элементу. В случае ширины все элементы блока, если не указано иное, имеют такую ​​же ширину, что и их родительские элементы, вплоть до <html>; таким образом, ширина элемента блока не зависит от его содержания и высказывания width: 50% дает четко определенное количество пикселей.

Однако высота элемента блока зависит от его содержимого, если вы не укажете конкретную высоту. Таким образом, существует обратная связь между родителем и ребенком в отношении роста и высказывания height: 50% не дает четко определенного значения, если вы не разорвете цикл обратной связи, задав родительскому элементу определенную высоту.

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

height имущество:

Давайте посмотрим, о чем говорит спецификация CSS Snapshot 2010 height:

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

Хорошо, давайте разберем это шаг за шагом:

Процент рассчитывается относительно высоты содержащего блока сгенерированного блока.

Что содержит блок? Это немного сложно, но для обычного элемента по умолчанию static позиция, это:

коробка предка контейнера ближайшего блока

или на английском языке, его родительский ящик. (Стоит знать, что это будет за fixed а также absolute позиции, но я игнорирую это, чтобы этот ответ был коротким.)

Итак, возьмите эти два примера:

<div   id="a"  style="width: 100px; height: 200px; background-color: orange">
  <div id="aa" style="width: 100px; height: 50%;   background-color: blue"></div>
</div>

<div   id="b"  style="width: 100px;              background-color: orange">
  <div id="bb" style="width: 100px; height: 50%; background-color: blue"></div>
</div>

В этом примере содержащий блок #aa является #a и так далее для #b а также #bb, Все идет нормально.

Следующее предложение спецификации для height это осложнение, которое я упомянул во введении к этому ответу:

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

Ага! Была ли явно указана высота содержащего блока!

  • 50% height:200px 100px в случае #aa
  • Но 50% height:auto является auto, что составляет 0px в случае #bb так как нет контента для auto расширить до

Как сказано в спецификации, также имеет значение, был ли содержащий блок полностью позиционирован или нет, но давайте перейдем к width,

width имущество:

Так ли это работает так же для width? Давайте посмотрим на спецификации:

Процент рассчитывается относительно ширины содержащего блока сгенерированного блока.

Взгляните на эти знакомые примеры, измененные от предыдущих, чтобы изменить width вместо height:

<div   id="c"  style="width: 200px; height: 100px; background-color: orange">
  <div id="cc" style="width: 50%;   height: 100px; background-color: blue"></div>
</div>

<div   id="d"  style="            height: 100px; background-color: orange">
  <div id="dd" style="width: 50%; height: 100px; background-color: blue"></div>
</div>

  • 50% width:200px 100px в случае #cc
  • 50% width:auto 50% от всего width:auto в конечном итоге, в отличие от height, нет специального правила, которое рассматривает этот случай по-другому.

Теперь вот немного хитрости: auto означает разные вещи, частично в зависимости от того, было ли это указано для width или же height! За height, это просто означало высоту, необходимую для размещения содержимого *, но для width, auto на самом деле сложнее. Вы можете видеть из фрагмента кода, который в данном случае оказался шириной области просмотра.

Что спецификация говорит об автоматическом значении ширины?

Ширина зависит от значений других свойств. Смотрите разделы ниже.

Вахи, это не полезно. Чтобы избавить вас от лишних хлопот, я нашел соответствующий раздел нашего варианта использования под названием "Расчет ширины и полей" с подзаголовком "Незаменяемые элементы уровня блока в нормальном потоке":

Следующие ограничения должны соблюдаться среди используемых значений других свойств:

'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = ширина содержащего блока

Итак width плюс соответствующие поля margin, border и padding должны складываться в ширину содержащего блока (не потомками height работает). Еще одно предложение спецификации:

Если для 'width' установлено значение 'auto', любые другие значения 'auto' становятся равными '0', а значение 'width' следует из полученного равенства.

Ага! Так что в этом случае 50% width:auto составляет 50% от области просмотра. Надеюсь, теперь все наконец-то имеет смысл!


Сноски

* По крайней мере, насколько это имеет значение в этом случае. Спец Хорошо, теперь все имеет смысл.

Я думаю, что вам просто нужно дать ему родительский контейнер... даже если высота этого контейнера определена в процентах. Это швы, чтобы работать просто отлично: JSFiddle

html, body { 
    margin: 0; 
    padding: 0; 
    width: 100%; 
    height: 100%;
}
.wrapper { 
    width: 100%; 
    height: 100%; 
}
.container { 
    width: 100%; 
    height: 50%; 
}

Другой вариант - добавить стиль в div.

<div style="position: absolute; height:somePercentage%; overflow:auto(or other overflow value)">
 //to be scrolled 
</div>

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

Вы должны дать ему контейнер с высотой. ширина использует область просмотра в качестве ширины по умолчанию

Без содержимого высота не имеет значения для расчета процента. Ширина, однако, будет брать процент от DOM, если родитель не указан. (Используя ваш пример) Поместив второй div в первый div, вы получите результат... пример ниже...

<div id="working">
  <div id="not-working"></div>
</div>

Второй div будет 30% от высоты первого div.

Другие вопросы по тегам