высота строки в процентах не работает

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и т. Д.).

BoltClock
источник
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)
}
Сантьяго Аризти
источник
Хотя все остальные ответы верны, это, вероятно, наиболее четкое и элегантное решение проблемы, указанной выше.
mstation
Не ответ, но очень полезный!
Alex
Не могли бы вы подробно объяснить, что там происходит? Я не совсем понимаю
Вальдриниум
1
@Valdrinit Я отредактирую ответ с дополнительными пояснениями
Сантьяго Аризти
36

Когда вы используете процент в качестве высоты строки, он основан не на контейнере div, а на размере шрифта.

Locrizak
источник
22

line-height: 100% был бы простым способом вертикального центрирования элементов, если бы он был рассчитан относительно контейнера, но это было бы слишком просто, поэтому он не работает.

Вместо этого это просто еще один способ сказать line-height: 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, попробуйте установить фиксированную ширину и высоту как для контейнера, так и для «центрального» дочернего элемента, убедившись, что дочерний элемент меньше, чем контейнер. Дочерний элемент должен оказаться в центре контейнера по горизонтали и вертикали.
Rolf
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блок просмотра. FIDDLE

line-height: 100vh;

Поддержка браузера

FelisPhasma
источник
Редкое законное использование 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

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

Чтобы выровнять предметы внутри .parentвас:

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

Вот и все. Дети 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 должно быть относительным.

Асраф Уд Духа
источник