vertical-align 属性 是如何工作的?
How does the vertical-align property work?
我不明白 vertical-align
什么时候可以,什么时候不能。
每次我 运行 进入 vertical-align
的用例时,似乎都在掷硬币,看它是否真的有效。我知道它必须应用于内联元素。我读到我必须为通常没有的元素指定 line-height
。我读到 height
属性 必须有一个静态 (non-auto/non-%) 值。我读过一些(现代)浏览器如果使用的元素不是自然的内联元素,则无法正确处理 vertical-align
。我不清楚 vertical-align
应该在包含元素上(如 text-align
)还是我想要垂直对齐的元素。
我创建了 this jsfiddle 来尝试解决问题,但仍然感到困惑。
#outer {
box-sizing: border-box;
border: red 1px solid;
height: 200px;
width: 400px;
text-align: center;
}
#inner {
border: blue 1px solid;
display: inline-block;
height: 200px;
vertical-align: middle;
}
#header {
border: green 1px solid;
display: inline-block;
line-height: 1em;
margin: 0;
}
<div id="outer">
<div id="inner">
<h1 id="header">
Some Text
</h1>
</div>
</div>
在上面的 jsfiddle 中,我希望 #header
位于 #outer
和 #inner
顶部和底部的中间位置。显然,事实并非如此。
简单的说:vertical-align
只有当它应用到的元素有display: inline-block
或ìnline
时才active/valid,例如,如果你想对齐,这很有用顶部边框处的一堆图像:您将它们定义为 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>
在您的 fiddle 中,元素相互嵌套,而不是彼此相邻,即它们不是兄弟姐妹 - 每个元素只有一个子元素,因此没有像上面的例子。
理解为什么添加多行文本不起作用的最简单方法,因为垂直对齐将在各自的行(行框)上对齐,而不是像您想象的那样在整个容器上对齐。
因此,如果我们添加更多文本,我们将得到以下内容。
#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-box,因此它的高度等于line box的高度,没有对齐的空间。
现在让我们增加行的高度(使用行高)
#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
非常接近,因为:
Aligns the middle of the element with the baseline plus half the x-height of the parentref
只差一半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>
Aligns the top of the element and its descendants with the top of the entire line.
具有相同的行高意味着该元素已经位于行框的顶部和底部,因此 top
bottom
将表现得像基线(默认值)。
line-box的高度也可以通过元素的高度来控制。您可能为一个元素设置了较大的字体大小,这将使行的高度更大,并且有足够的空间在同一个行框中对齐其旁边的小文本:
#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
元素的高度来控制line box:
#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
对齐,您应该有一个高度足够大的行框(明确设置或由其他元素设置)可以对齐你的元素。如果您的元素正在定义行框(这是常见的情况),则没有任何内容需要对齐。
一些好问题需要更多的细节:
My inline-block elements are not lining up properly
Why is this inline-block element pushed downward?
我不明白 vertical-align
什么时候可以,什么时候不能。
每次我 运行 进入 vertical-align
的用例时,似乎都在掷硬币,看它是否真的有效。我知道它必须应用于内联元素。我读到我必须为通常没有的元素指定 line-height
。我读到 height
属性 必须有一个静态 (non-auto/non-%) 值。我读过一些(现代)浏览器如果使用的元素不是自然的内联元素,则无法正确处理 vertical-align
。我不清楚 vertical-align
应该在包含元素上(如 text-align
)还是我想要垂直对齐的元素。
我创建了 this jsfiddle 来尝试解决问题,但仍然感到困惑。
#outer {
box-sizing: border-box;
border: red 1px solid;
height: 200px;
width: 400px;
text-align: center;
}
#inner {
border: blue 1px solid;
display: inline-block;
height: 200px;
vertical-align: middle;
}
#header {
border: green 1px solid;
display: inline-block;
line-height: 1em;
margin: 0;
}
<div id="outer">
<div id="inner">
<h1 id="header">
Some Text
</h1>
</div>
</div>
在上面的 jsfiddle 中,我希望 #header
位于 #outer
和 #inner
顶部和底部的中间位置。显然,事实并非如此。
简单的说:vertical-align
只有当它应用到的元素有display: inline-block
或ìnline
时才active/valid,例如,如果你想对齐,这很有用顶部边框处的一堆图像:您将它们定义为 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>
在您的 fiddle 中,元素相互嵌套,而不是彼此相邻,即它们不是兄弟姐妹 - 每个元素只有一个子元素,因此没有像上面的例子。
理解为什么添加多行文本不起作用的最简单方法,因为垂直对齐将在各自的行(行框)上对齐,而不是像您想象的那样在整个容器上对齐。
因此,如果我们添加更多文本,我们将得到以下内容。
#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-box,因此它的高度等于line box的高度,没有对齐的空间。
现在让我们增加行的高度(使用行高)
#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
非常接近,因为:
Aligns the middle of the element with the baseline plus half the x-height of the parentref
只差一半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>
Aligns the top of the element and its descendants with the top of the entire line.
具有相同的行高意味着该元素已经位于行框的顶部和底部,因此 top
bottom
将表现得像基线(默认值)。
line-box的高度也可以通过元素的高度来控制。您可能为一个元素设置了较大的字体大小,这将使行的高度更大,并且有足够的空间在同一个行框中对齐其旁边的小文本:
#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
元素的高度来控制line box:
#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
对齐,您应该有一个高度足够大的行框(明确设置或由其他元素设置)可以对齐你的元素。如果您的元素正在定义行框(这是常见的情况),则没有任何内容需要对齐。
一些好问题需要更多的细节:
My inline-block elements are not lining up properly
Why is this inline-block element pushed downward?