Як встановити поле або прокладку у відсотках від висоти батьківського контейнера?


236

Я ламав мізки над створенням вертикального вирівнювання в css, використовуючи наступне

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

    .vert-align{
		padding-top:50%;
		height:50%;
	}
<!-- and used the following div structure. -->

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

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

Чи є спосіб встановити прокладку та / або запас у відсотках від висоти, не вдаючись до використання JavaScript?

Відповіді:


223

Виправлення , що так, вертикальне заповнення і рентабельність в порівнянні з шириною, але topі bottom не є.

Тож просто помістіть div у інший, а у внутрішньому div використовуйте щось на зразок top:50%(пам’ятайте, що positionмає значення, якщо він все ще не працює)


3
topвідмінно підходить для зміни розміру на основі висоти браузера / вікна. Як щодо того, щоб під цим дівом не було діва? Як ти можеш, clearщоб другий дів опинився під дівом, який зміщується вниз top:50%??
Федеріко

Дізнайтеся, що нового. Не знав, вертикальні прокладки і запас відносні до ширини раніше. Дякую.
шаош

5
Також можна додати роздільник 'spacer' із заданою висотою відсотка. Здається, трохи брудно, але це працює. дивіться цю відповідь .
WCByrne

4
Що вічний @%! ^? Чому вертикальні запаси та прокладки відносно ширини ? ЩО? Чому на землі було прийнято таке рішення?
тимчасовий_користувач

Ваша відповідь вкрай непропорційно підкреслена порівняно з відповіддю Алаїна нижче, що дає загальне рішення, і я вважав це дуже корисним і майже не бачив. top: 50%не дуже корисно, якщо вам потрібно вирівняти вміст за власним центром.
okovko

35

Відповідь на дещо інше запитання: Ви можете використовувати vhодиниці, щоб розмістити елементи до центру вікна перегляду :

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

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

Чому ця відповідь не проголосується вище? Щось не так у використанні vh?
АланH

3
Це тому, що це не відповідь, пристосований до оригінального питання, це корисна хитрість, яка працює лише в кількох суміжних випадках.
willoller

використання vhмайже те саме, що відсотки ... в деяких випадках ще гірше. Ця відповідь не має значення для запитання
vsync

33

Ось два варіанти наслідування потрібної поведінки. Не загальне рішення, але може допомогти в деяких випадках. Вертикальний інтервал тут обчислюється виходячи з розміру зовнішнього елемента, а не його батьківського, але сам цей розмір може бути відносним до батьківського, і таким чином інтервал буде також відносним.

<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%;
}

10

Для того, щоб дочірній елемент розміщувався абсолютно з його батьківського елемента, потрібно встановити відносне положення на батьківському елементі І абсолютне положення на дочірньому елементі.

Тоді на дочірнім елементі '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>

Є ще одне рішення за допомогою флеш-коробки.

.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>

Ви знайдете переваги / недоліки для обох.


1
Використання перекладу - єдиний реальний спосіб переміщення елемента по вертикалі відносно його власного розміру.
Еран Голдін

Дякую за це Це має бути обрана відповідь.
Вессам Ель Махді

6

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

З специфікації :

. . . відсотки від властивостей запасу та прокладки, які завжди розраховуються відносно ширини блоку, що міститься в CSS2.1, обчислюються щодо розміру вбудованого блоку, що містить у 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>

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


Це, IMO, було б більш елегантним рішенням, але (станом на 05.05.2018) вертикальні режими запису недостатньо підтримуються . Сподіваємось, що незабаром зміниться.
zanerock

1
@zanerock Я досить впевнений, що таблиця компактних MDN застаріла. Наприклад, в ньому йдеться про те, що Safari потребує -webkit-префікса, але згідно з каніусом він не потребував префікса з Safari 11. Ви спробували його з будь-яким браузером, у якому він не працював?
Джеймс Т

1
Ні, я повинен визнати, що я просто припускав, що це добре, навіть автоматизовано.
zanerock

4

Інший спосіб центрувати текст одного рядка:

.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;
}

0

На 50% прокладки не буде центр вашої дитини, він розмістить його нижче центру. Думаю, вам дуже хочеться 25% накладки. Можливо, у вас просто не вистачає місця, оскільки ваш вміст стає вище? Ви також спробували встановити margin-top замість padding-top?

EDIT: Nevermind, йдеться на сайті w3schools

% Вказує прокладку у відсотках від ширини елемента, що містить

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

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


1
Дякую, Сліфф. Я розумію, що мої 50% не будуть зосереджувати вміст діви. Насправді у мене є лише один рядок тексту, який потрібно зосереджувати вертикально. Дякую за посилання, хоча!
Райан

3
Якщо це лише один рядок тексту, ви вважали, що ви використовуєте смішно великий line-height, тобто зробіть висоту рядка 200 пікселів?
SpliFF

@Ryan щодо центрування тексту вертикально, див. Stackoverflow.com/questions/8865458/…
користувач

ваше посилання розірвано
quemeful

0

Це дуже цікава помилка. (На мою думку, це все-таки помилка) Приємна знахідка!

Щодо того, як це встановити, я би рекомендував відповідь Каміло Мартіна. А щодо того , чому я хотів би трохи пояснити це, якщо ви, хлопці, не проти.


У специфікаціях CSS я знайшов:

'padding'
Відсотки: відносяться до ширини блоку, що містить

... що дивно, але добре.

Отже, з батьком width: 210pxі дитиною padding-top: 50%я отримую розраховане / обчислене значення padding-top: 96.5px- що не є очікуваним 105px.

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


Існує причина , по специфікації, і це пояснює краще: hongkiat.com/blog/calculate-css-percentage-margins
manikanta
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.