Самый простой способ понять, почему не работает, это добавить много строк текста, потому что вертикальное выравнивание будет выравниваться по соответствующей строке (строковому блоку), а не по всему контейнеру, как вы думаете.
Итак, если мы добавим больше текста, у нас будет следующее.
#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
у вас должен быть линейный ящик, высота которого достаточно велика (явно установлена или установлена другими элементами), где вы можете выровнять свой элемент. Если ваш элемент определяет строковое поле (что является общим случаем), то выравнивать нечего.
Несколько хороших вопросов, чтобы иметь больше деталей:
Выравнивание по вертикали не работает для встроенного блока
Встроенные элементы и высота строки
Мои элементы встроенного блока не выстраиваются должным образом
Почему этот элемент встроенного блока перемещается вниз?