Я не "получаю" свойство css вертикального выравнивания - PullRequest
0 голосов
/ 15 января 2019

Я не понимаю, когда vertical-align будет и не будет работать.

Каждый раз, когда я сталкиваюсь с вариантом использования для vertical-align, мне кажется, что это бросок монеты о том, будет ли он на самом деле работать. Я знаю, что это должно быть применено к встроенным элементам. Я прочитал, что я должен указать line-height для элементов, которые обычно не имеют его. Я прочитал, что свойство height должно иметь статическое (не авто / не%) значение. Я читал, что некоторые (современные) браузеры неправильно обрабатывают vertical-align, если элемент, на котором они используются, не является встроенным элементом. Мне неясно, должен ли vertical-align быть на содержащем элементе (например, text-align) или элемент, который я хочу выровнять по вертикали.

Я создал этот jsfiddle , чтобы попытаться решить проблему, но остался в замешательстве.

В jsfiddle выше я бы ожидал, что #header будет посередине между верхом и низом #outer и #inner. Очевидно, что это не так.

Ответы [ 2 ]

0 голосов
/ 15 января 2019

Самый простой способ понять, почему не работает, это добавить много строк текста, потому что вертикальное выравнивание будет выравниваться по соответствующей строке (строковому блоку), а не по всему контейнеру, как вы думаете.

Итак, если мы добавим больше текста, у нас будет следующее.

#outer {
  box-sizing: border-box;
  border: red 1px solid;
  height: 200px;
  text-align: center;
}

#inner {
  border: blue 1px solid;
  height: 200px;
  width:180px;
  display: inline-block;
  overflow:hidden;
}

.header {
  display: inline;
  border: green 1px solid;
  margin: 0;
}
<div id="outer">
  <div id="inner">
    <h1 class="header">
      Some Text Some Text Some Text
    </h1>
  </div>
  <div id="inner">
    <h1 class="header" style="vertical-align:middle;">
      Some Text Some Text Some Text
    </h1>
  </div>
  <div id="inner">
    <h1 class="header" style="vertical-align:top;">
      Some Text Some Text Some Text
    </h1>
  </div>
</div>

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

Теперь давайте увеличим высоту строки (используя line-height)

#outer {
  box-sizing: border-box;
  border: red 1px solid;
  height: 200px;
  text-align: center;
}

#inner {
  border: blue 1px solid;
  height: 200px;
  width:180px;
  line-height:200px;
  display: inline-block;
}

.header {
  display: inline;
  border: green 1px solid;
  margin: 0;
  line-height:1em;
}
<div id="outer">
  <div id="inner">
    <h1 class="header">
      Some Text Some Text Some Text
    </h1>
  </div>
  <div id="inner">
    <h1 class="header" style="vertical-align:middle;">
      Some Text Some Text Some Text
    </h1>
  </div>
  <div id="inner">
    <h1 class="header" style="vertical-align:top;">
      Some Text Some Text Some Text
    </h1>
  </div>
</div>

Посмотрите, как теперь каждая строка больше и каждый текст выровнен по соответствующей строке, которая имеет высоту 200px, и мы можем ясно видеть, как выравнивание отличается.

В этом случае текст имеет достаточно места для выравнивания, как вы хотите, и мы видим магию, если мы сохраняем только одну строку текста:

#outer {
  box-sizing: border-box;
  border: red 1px solid;
  height: 200px;
  text-align: center;
}

#inner {
  border: blue 1px solid;
  height: 200px;
  line-height: 200px;
  display: inline-block;
}

.header {
  display: inline;
  border: green 1px solid;
  margin: 0;
  line-height:1em;
}
<div id="outer">
  <div id="inner">
    <h1 class="header">
      Some Text
    </h1>
    <h1 class="header" style="vertical-align:middle">
      Some Text
    </h1>
    <h1 class="header" style="vertical-align:top">
      Some Text
    </h1>
    <h1 class="header" style="vertical-align:bottom">
      Some Text
    </h1>
  </div>
</div>

Вы также можете заметить, как middle и baseline очень близки, потому что:

Выравнивает середину элемента с базовой линией и половиной x-высоты родительского элемента ref

Существует только половина x-height разницы.

Еще один важный факт, на который следует обратить внимание: если мы не установим высоту строки для встроенного элемента, он унаследует высоту строки его родителя, и выравнивание, подобное top, не будет иметь никакого эффекта.

#outer {
  box-sizing: border-box;
  border: red 1px solid;
  height: 200px;
  text-align: center;
}

#inner {
  border: blue 1px solid;
  height: 200px;
  line-height: 200px;
  display: inline-block;
}

.header {
  display: inline;
  border: green 1px solid;
  margin: 0;
}
<div id="outer">
  <div id="inner">
    <h1 class="header">
      Some Text
    </h1>
    <h1 class="header" style="vertical-align:middle">
      Some Text
    </h1>
    <h1 class="header" style="vertical-align:top">
      Some Text
    </h1>
  </div>
</div>

Выравнивает верх элемента и его потомков с верхом всей строки.

Наличие одинаковой высоты строки означает, что элемент уже находится сверху, а также в нижней части линейного блока, поэтому оба параметра top bottom будут вести себя как базовая линия (значение по умолчанию).


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

#outer {
  box-sizing: border-box;
  border: red 1px solid;
  height: 200px;
  text-align: center;
}

#inner {
  border: blue 1px solid;
  height: 200px;
  display: inline-block;
}

.header {
  display: inline;
  border: green 1px solid;
  margin: 0;
}
@keyframes change {
  from {font-size:20px;}
  to {font-size:100px;}
}
<div id="outer">
  <div id="inner">
    <h1 class="header">
      Text
    </h1>
    <h1 class="header" style="font-size:100px;animation:change 5s linear alternate infinite">
      T
    </h1>
    <h1 class="header" style="vertical-align:middle;">
      Text
    </h1>
    <h1 class="header" style="vertical-align:top;">
      Text
    </h1>
    <h1 class="header" style="vertical-align:bottom;">
      Text
    </h1>
  </div>
</div>

Вы также можете настроить линейный блок, установив высоту элемента inline-block:

#outer {
  box-sizing: border-box;
  border: red 1px solid;
  height: 200px;
  text-align: center;
}

#inner {
  border: blue 1px solid;
  height: 200px;
  display: inline-block;
}

.header {
  display: inline;
  border: green 1px solid;
  margin: 0;
}
.elem {
 display:inline-block;
 background:red;
 width:2px;
 height:5px;
 animation:change 5s linear alternate infinite;
}
@keyframes change {
  from {height:20px;}
  to {height:100px;}
}
<div id="outer">
  <div id="inner">
    <h1 class="header">
      Text
    </h1>
    <div class="elem">
    </div>
    <h1 class="header" style="vertical-align:middle;">
      Text
    </h1>
    <h1 class="header" style="vertical-align:top;">
      Text
    </h1>
    <h1 class="header" style="vertical-align:bottom;">
      Text
    </h1>
  </div>
</div>

В заключение: для выравнивания с использованием vertical-align у вас должен быть линейный ящик, высота которого достаточно велика (явно установлена ​​или установлена ​​другими элементами), где вы можете выровнять свой элемент. Если ваш элемент определяет строковое поле (что является общим случаем), то выравнивать нечего.


Несколько хороших вопросов, чтобы иметь больше деталей:

Выравнивание по вертикали не работает для встроенного блока

Встроенные элементы и высота строки

Мои элементы встроенного блока не выстраиваются должным образом

Почему этот элемент встроенного блока перемещается вниз?

0 голосов
/ 15 января 2019

Проще говоря: vertical-align активен / действителен, только если элемент, к которому он применяется, имеет display: inline-block или ìnline, что, например, полезно, если вы хотите выровнять группу изображений по их верхней границе: Вы определите их как inline-blocks и примените vertical-align: top к ним

Вот пример:

.wrapper {
  height: 250px;
  border: 1px solid green;
}

.wrapper>img {
  display: inline-block;
  vertical-align: top;
}
<div class="wrapper">
  <img src="https://placehold.it/120x40">
  <img src="https://placehold.it/70x140">
  <img src="https://placehold.it/80x60">
  <img src="https://placehold.it/60x140">
</div>

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

...