висота рядка у відсотках не працює


87

У мене проблема з висотою лінії, яку я не можу повністю розвести.

Наступний код буде центрувати зображення в div:

CSS

.bar {
    height: 800px;
    width: 100%;
    line-height:800px;
    background-color: #000;
    text-align: center; 
}

.bar img {
    vertical-align: middle;   
}

HTML

<div class="bar">
    <img src="http://27.media.tumblr.com/yHWA4oxH870ulxnoH7CkOSDR_500.jpg" alt="Foo Image" />
</div>

Однак, якщо я зміню висоту рядка на 100%, тоді висота рядка не набуває чинності (або, принаймні, не стає 100% від div).

Приклад jsfiddle

Хтось знає, що я роблю не так?

Відповіді:


194

line-height: 100%означає 100% розміру шрифту для цього елемента, а не 100% його висоти. Насправді, висота рядка завжди залежить від розміру шрифту, а НЕ висоту, якщо його значення не використовує одиницю довжини (абсолютної px, ptі т.д.).


3
Ага. Мене завжди дурять дурні помилки. Дякую! Я прийму вашу відповідь, коли це дозволить.
Моя голова болить

1
Очевидно, автори специфікації помилково вважали, що ніхто не захоче встановлювати розмір шрифту / висоту рядка відносно висоти елемента ...
Енді,

1
@Andy: Гарною (?) Новиною є те, що незабаром це стане можливим завдяки використанню каскадних змінних . Лише кілька років очікування ...
BoltClock

@BoltClock ах, круто! Це буде приємно. Дякую що дали мені знати!
Енді,

vh - виняток. У CSS3, якщо ви встановите його як 100vh, він насправді буде працювати так, як це можуть вимагати деякі розробники. Однак зверніть увагу, що це не працює у старих браузерах, які не підтримують CSS3.
Philll_t

97

Я знаю, що це питання давнє, але я виявив, що для мене це ідеальне рішення.

Я додаю цей css до div, який я хочу відцентрувати:

div:before {
  content: "";
  display: inline-block;
  height: 100%;
  vertical-align: middle;
}

Це працює кожного разу, і це чисто.

Редагувати: Просто для завершення, я використовую scss, і у мене є зручний мікс, який я включаю до кожного з батьків, хто є прямими дітьми, яких я хочу мати по вертикалі:

@mixin vertical-align($align: middle) {
  &:before {
    content: "";
    display: inline-block;
    height: 100%;
    vertical-align: $align;
    // you can add font-size 0 here and restore in the children to prevent
    // the inline-block white-space to mess the width of your elements
    font-size: 0;
  }
  & > * {
    vertical-align: $align;
    // although you need to know the font-size, because "inherit" is 0
    font-size: 14px;
  }
}

Повне пояснення: div:beforeдодасть елемент всередині div, але перед будь-яким із його дочірніх елементів. Коли ми використовуємо :beforeабо :afterми повинні використовувати content:декларацію, інакше нічого не трапиться, але для нашої мети вміст може бути порожнім. Тоді ми говоримо, що елемент має бути таким же високим, як його батьківський, доки визначена висота його батьківського елемента, і цей елемент має принаймні вбудований блок. vertical-alignвизначає вертикальне положення самовідношення до батьків, на відміну від того, text-alignщо працює по-іншому.

@mixinДекларація для користувачів Sass і він буде використовуватися , як це:

div {
    @include vertical-align(middle)
}

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

Не відповідь, але найкорисніший!
Олексій

Не могли б ви детально пояснити, що там відбувається? Я не зовсім розумію
Valdrinium

1
@Valdrinit Я відредагую відповідь з додатковими поясненнями
santiago arizti

36

Коли ви використовуєте відсоток як висоту рядка, він не базується на контейнері div, а на основі розміру шрифту.


22

line-height: 100% було б простим способом вертикального центрування елементів, якби це було розраховано по відношенню до контейнера, але це було б занадто просто, отже, це не працює.

Отже, замість цього, це просто інший спосіб сказати висоту рядка: 1em (так?)

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

.container {
     position:relative;
}
.center {
     position:absolute;
     top:0; left:0; bottom:0; right:0;
     margin: auto;
     /* for horiz left-align, try "margin: auto auto auto 0" */
}

1
Це не працює для мене ... не впевнений, що я щось пропускаю.
clifgriffin

1
@clifgriffin, спробуйте встановити фіксовану ширину та висоту як для контейнера, так і для "центрального" дочірнього об'єкта, переконавшись, що дочірній матеріал менше, ніж тоді контейнер. Дитина повинна опинитися в центрі горизонтально та вертикально всередині контейнера.
Рольф

22
це було б занадто просто, отже, це не працює +1 :-)
elipoultorak

@clifgriffin переконайтесь, що контейнер має правильну ширину та висоту, ви можете відцентрувати все в div однакового розміру. Це було коригування, яке мені довелося зробити.
Девід Керріган,

@ user3576887 "це було б занадто просто, отже, це не спрацьовує", саме тому я і проти цього - є дуже вагома причина, чому це працює не так, як ви хотіли б тут, і цього не повинно бути затемнене з метою розваги, критики або чого б там не було.
TheThirdMan

11

може бути, і не гарненьке, але воно працює і має свою семантику;

<div class="bar" style="display: table; text-align: center;">
    <img style="display: table-cell; vertical-align: middle;" src="http://27.media.tumblr.com/yHWA4oxH870ulxnoH7CkOSDR_500.jpg" alt="Foo Image" />
</div>

display: table-cell надає елементу унікальну здатність таблиці для вертикального вирівнювання (принаймні, я думаю, що це унікально)


Дякую за відповідь, я спробував ваш код, але, здається, це не працює для мене.
Моя голова болить

хм, це трохи дивно; якщо ви можете опублікувати трохи свого коду, щоб я міг його уважніше розглянути, я міг би допомогти ще
Йоган Олссон,

Олссон - я щойно вставив ваш код у JSFiddle, і він не спрацював. Дякую за пропозицію допомоги - але я можу поки що встановити абсолютну висоту лінії. Якщо це зміниться, я розгляну далі вашу відповідь. Ще раз спасибі за допомогу!
Моя голова болить

6

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

line-height: 100vh;

Підтримка браузера


Рідкісне законне використання vh замість%.
cytsunny

1

Це рішення працює в IE9 і вище. Спочатку ми встановлюємо верхнє положення дитини на 50% (посередині батьків). Потім, використовуючи translateправило, змістіть дитину вгору на половину її фактичного зросту. Основна перевага полягає в тому, що нам не потрібно визначати зріст дитини, він обчислюється браузером динамічно. JSFiddle

.bar {
    height: 500px;
    text-align: center;
    background: green;
}
.bar img {
    position: relative;
    top: 50%;
    transform: translate(0, -50%);
}

1

Більш сучасний підхід - використовувати для цього флексбокс, він простіший і чистіший. Однак, флексбокс - це зовсім інша парадигма від того inline-block, що було floatчи було positionраніше.

Щоб вирівняти елементи всередині .parent, виконайте такі дії:

.parent {
  display: flex;
  align-items: center;
}

Ось про це. Діти flexбатьків автоматично перетворюються на дитячі предмети flex.

Вам слід прочитати більше про flexbox, гарне місце для початку - це шпаргалка: https://css-tricks.com/snippets/css/a-guide-to-flexbox/


0

Ви можете встановити висоту рядка на основі висоти цього елемента. Якщо висота елемента 200 пікселів означає, що вам потрібно встановити висоту рядка на 200 пікселів для центрування тексту.

span {
  height: 200px;
  width: 200px; 
  border: 1px solid black;
  line-height: 200px; 
  display: block;
}
<span>Im vertically center</span>


0

Це сучасне рішення, в якому вам потрібно встановити наступний CSS у контейнері div або зовнішньому div.

.outer-div {
  display: flex;
  justify-content: center;
  align-items: center; 
}

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

.inner-div {
    position: absolute;
    top: 50%; 
    left: 50%;
    transform: translate(-50%,-50%);
    text-align: center;
}

Зверніть увагу, що зовнішня або контейнерна позиція div повинна бути відносною.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.