it-swarm-ru.tech

Как установить поле или отступ в процентах от высоты родительского контейнера?

Я ломал голову над созданием вертикального выравнивания в CSS, используя следующее

.base{
    background-color:green;
    width:200px;
    height:200px;
    overflow:auto;
    position:relative;
}

.vert-align{
    padding-top:50%;
    height:50%;
}

и использовал следующую структуру div.

<div class="base">
   <div class="vert-align">
       Content Here
   </div>
</div>

Хотя в этом случае это работало, я был удивлен, что, когда я увеличивал или уменьшал ширину моего базового элемента div, вертикальное выравнивание зависало. Я ожидал, что когда я установлю свойство padding-top, он будет принимать отступ в процентах от высоты родительского контейнера, который в нашем случае является базовым, но указанное выше значение в 50 процентов рассчитывается как процент от ширина. :(

Есть ли способ установить отступы и/или поля в процентах от высоты, не прибегая к использованию JavaScript? 

199
Ryan

Исправление заключается в том, что да, отступы по вертикали и поля относятся к ширине, а top и bottom- _ нет.

Так что просто поместите div внутри другого, а во внутреннем div используйте что-то вроде top:50% (помните, position имеет значение, если он все еще не работает)

198
Camilo Martin

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

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

Первый вариант: использовать псевдоэлементы, здесь вертикальное и горизонтальное расстояние относительно внешнего. Демо

#outer::before, #outer::after {
    display: block;
    content: "";
    height: 10%;
}
#inner {
    height: 80%;
    margin-left: 10%;
    margin-right: 10%;
}

Перемещение горизонтального промежутка к внешнему элементу делает его относительно родительского элемента внешнего. Демо

#outer {
    padding-left: 10%;
    padding-right: 10%;
}

Второй вариант: использовать абсолютное позиционирование. Демо

#outer {
    position: relative;
}
#inner {
    position: absolute;
    left: 10%;
    right: 10%;
    top: 10%;
    bottom: 10%;
}
30
user

Ответ на немного другой вопрос: Вы можете использовать vh единицы, чтобы добавить элементы к центру области просмотра :

.centerme {
    margin-top: 50vh;
    background: red;
}

<div class="centerme">middle</div>
29
willoller

Чтобы сделать дочерний элемент абсолютно позиционированным относительно его родительского элемента, вам необходимо установить относительную позицию на родительском элементе И абсолютную позицию на дочернем элементе. 

Тогда на дочернем элементе 'top' относительно высоты родительского элемента. Поэтому вам также нужно «перевести» ребенка на 50% выше его собственного роста.

.base{
    background-color: green;
    width: 200px;
    height: 200px;
    overflow: auto;
    position: relative;
}
    
.vert-align {
    position: absolute;
    top: 50%;
    transform: translate(0, -50%);
}
    <div class="base">
        <div class="vert-align">
            Content Here
        </div>
    </div>

Существует еще одно решение с использованием flex box.

.base{
    background-color:green;
    width: 200px;
    height: 200px;
    overflow: auto;
    display: flex;
    align-items: center;
}
<div class="base">
    <div class="vert-align">
        Content Here
    </div>
</div>

Вы найдете преимущества/недостатки для обоих.

10
alain

Другой способ центрировать одну строку текста:

.parent{
  position: relative;
}

.child{
   position: absolute;
   top: 50%;
   line-height: 0;
}

или просто

.parent{
  overflow: hidden; /* if this ins't here the parent will adopt the 50% margin of the child */
}

.child{
   margin-top: 50%;
   line-height: 0;
}
3
rawiro

50% -ая обивка не отцентрирует вашего ребенка, она поместит его ниже центра. Я думаю, что вы действительно хотите, чтобы верхний слой составлял 25%. Может быть, вам просто не хватает места, поскольку ваш контент становится выше? Также вы пытались установить поле margin вместо top?

Правка: Nevermind, сайт w3schools говорит 

% Определяет отступ в процентах от ширины содержащего элемента.

Так может быть, он всегда использует ширину? Я никогда не замечал.

То, что вы делаете, может быть достигнуто с помощью display: table, хотя (по крайней мере, для современных браузеров). Техника объясняется здесь .

1
SpliFF

Это может быть достигнуто с помощью свойства writing-mode . Если вы установите writing-mode элемента в вертикальный режим записи, такой как vertical-lr, процентные значения его потомков для заполнения и поля в обоих измерениях станут относительными к высоте, а не к ширине.

Из спецификации :

, , , проценты на полях и свойствах заполнения, которые всегда рассчитываются относительно ширины содержащего блока в CSS2.1, рассчитываются относительно inline size содержащего блока в CSS3.

Определение встроенный размер :

Измерение в линейном измерении: относится к физической ширине (горизонтальному измерению) в режимах горизонтальной записи и к физической высоте (вертикальному измерению) в режимах вертикальной записи. 

Например, с изменяемым размером элемента, где горизонтальные поля относятся к ширине, а вертикальные поля - к высоте.

.resize {
  width: 400px;
  height: 200px;
  resize: both;
  overflow: hidden;
}

.outer {
  height: 100%;
  background-color: red;
}

.middle {
  writing-mode: vertical-lr;
  margin: 0 10%;
  width: 80%;
  height: 100%;
  background-color: yellow;
}

.inner {
  writing-mode: horizontal-tb;
  margin: 10% 0;
  width: 100%;
  height: 80%;
  background-color: blue;
}
<div class="resize">
  <div class="outer">
    <div class="middle">
      <div class="inner"></div>
    </div>
  </div>
</div>

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

1
James T

Это очень интересная ошибка. (На мой взгляд, это все равно ошибка) Хорошая находка!

Что касается как, чтобы установить его, я бы порекомендовал ответ Камило Мартина. Но что касается почему, я бы хотел немного объяснить это, если вы, ребята, не против.


В спецификации CSS я нашел:

'padding'
Percentages: относится к ширине содержащего блока

... что странно, но хорошо.

Итак, с родительским width: 210px и дочерним padding-top: 50% я получаю вычисленное/вычисленное значение padding-top: 96.5px - которое не является ожидаемым 105px.

Это связано с тем, что в Windows (я не уверен насчет других ОС) размер общих полос прокрутки по умолчанию 17px × 100% (или 100% × 17px для горизонтальных полос). Эти 17px вычитаются перед, вычисляя 50%, следовательно, 50% of 193px = 96.5px.

0
WoodrowShigeru