Если вы посмотрите на спецификацию блочной модели CSS , вы увидите следующее:
Процент [маржа] рассчитывается относительно ширины содержащего блока сгенерированного бокса. Обратите внимание, что это верно и для полей «верхний край» и «нижний край». Если ширина содержащего блока зависит от этого элемента, то результирующий макет не определен в CSS 2.1. (курсив мой)
Это действительно правда. Но почему ? Что, черт возьми, могло заставить кого-нибудь так спроектировать его? Легко придумать сценарии, в которых вы хотите, например, определенная вещь всегда должна быть на 25% ниже верхней части страницы, но трудно придумать какую-либо причину, по которой вы хотите, чтобы вертикальное заполнение было относительно горизонтального размера родитель.
Вот пример явления, о котором я говорю:
<div style="border: 1px solid red; margin: 0; padding: 0; width: 200px; height: 800px;">
This div is 200x800.
<div style="border: 1px solid blue; margin: 10% 0 0 10%;">
This div has top-margin of 10% and left-margin of 10% with respect to its parent.
</div>
</div>
margin: 25%
самом деле означает. Это не было бы равным запасом, даже если код предполагает, что это так. У меня нет доказательств, подтверждающих это, но это кажется разумным.height: 10%; width: 10%
вы тоже не получите квадратный элемент.Note that in a horizontal flow, percentages on ‘margin-top’ and ‘margin-bottom’ are relative to the width of the containing block, not the height (and in vertical flow, ‘margin-left’ and ‘margin-right’ are relative to the height, not the width).
Так что все идет в обе стороны»Ответы:
Переношу свой комментарий в ответ, потому что это имеет логический смысл. Однако учтите, что это безосновательное предположение. Фактическое объяснение того, почему спецификация написана таким образом, технически до сих пор неизвестно.
Обновление: последние пару предложений могут быть не совсем точными. Высота листового элемента (дочерний элемент без дочерних элементов) влияет на высоту всех элементов над ним, поэтому это влияет на множество различных ситуаций.
источник
h_p
. Верхнее заполнение 10% будет составлять высоту дочернего элементаh_c = h_ci + 0.1h_p
, гдеh_ci
- внутренняя высота дочернего элемента и не зависит от высоты родительского элемента. Для одного ребенка вы просто найдете родительский рост из уравненияh_p = h_ci + 0.1h_p
=>h_p = h_ci / 0.9
. Вы всегда можете сделать это, независимо от того, сколько у вас детей, даже при разном заполнении. Это всего лишь одно неизвестное (h_p
) и одно уравнение.width
приводит к одной и той же проблеме по горизонтали.Чтобы поле «n%» (и отступы) было одинаковым для margin-top / margin-right / margin-bottom / margin-left, все четыре должны относиться к одной и той же базе. Если бы верх / низ использовали другое основание, чем левое / правое ', тогда поле «n%» (и отступы) не означало бы одно и то же на всех четырех сторонах.
(Также обратите внимание, что наличие верхнего / нижнего поля относительно ширины позволяет использовать странный CSS-хак, который позволяет вам указать поле с неизменным соотношением сторон ... даже если поле масштабируется.)
источник
padding: n [type]
. Таким образом, у вас будетpadding: 5% logical
(что предлагает OP), а неpadding: 5% width
со вторым параметром, по умолчанию равным «ширине» для обратной совместимости.Я голосую за ответ от @ChuckKollars после игры с этим JSFiddle (в Chrome 46.0.2490.86) и ссылки на этот пост (написанный на китайском языке).
Основная причина против гипотезы о бесконечном вычислении заключается в том, что использование
width
сталкивается с той же проблемой бесконечного вычисления .Взгляните на этот JSFiddle ,
parent
дисплейinline-block
, который имеет право определять поля / отступы на нем.child
Имеет значение рентабельности20%
. Если мы последуем гипотезе бесконечного вычисления :child
зависит отparent
parent
зависит отchild
Но в результате Chrome где-то останавливает вычисление, в результате чего:
Если вы попытаетесь развернуть панель «результатов» по горизонтали в JSFiddle, вы обнаружите, что их ширина не изменится. Обратите внимание, что содержимое в
child
теге разделено на две строки (а не, скажем, на одну строку), почему? Думаю, Chrome просто где-то жестко закодировал. Если вы отредактируетеchild
контент, чтобы сделать его больше ( JSFiddle ), вы обнаружите, что, пока есть дополнительное пространство по горизонтали, Chrome сохраняет содержимое двух строк.Итак, мы видим: есть способ предотвратить бесконечный расчет .
Я согласен с предположением о том, что: этот дизайн предназначен для сохранения четырех значений полей / отступов, основанных на одной и той же мере.
этот пост (написанный на китайском языке) также предлагает другую причину: это из-за ориентации чтения / набора. Мы читаем сверху вниз с фиксированной шириной и бесконечной высотой (виртуально).
источник
Я понимаю, что OP спрашивает, почему спецификация CSS определяет процентное соотношение верхнего / нижнего поля в процентах от ширины (а не, как можно было бы предположить, высоты), но я подумал, что также может быть полезно опубликовать потенциальное решение.
Большинство современных браузеров теперь поддерживают vw и vh, что позволяет указывать номера полей в зависимости от ширины и высоты области просмотра.
100vw / 100vh равняется 100% ширины / 100% высоты (соответственно), если нет полосы прокрутки; если есть полоса прокрутки, номера окна просмотра не учитывают это (в то время как числа% учитывают). К счастью, почти все браузеры используют полосу прокрутки размером 17 пикселей ( см. Здесь ), поэтому вы можете использовать функцию css calc, чтобы учесть это. Если вы не знаете, появится ли полоса прокрутки или нет, это решение не сработает.
Например: при отсутствии горизонтальной полосы прокрутки верхнее поле в 50% от высоты можно определить как «margin-top: 50vh;». С горизонтальной полосой прокрутки это можно определить как «margin-top: calc (0.5 * (100vh - 17px));» (помните, что операторы «минус» и «плюс» в calc требуют пробелов с обеих сторон!).
источник