vertical-align 支持的属性值及组成
- inherit
- 线类
baseline, top, middle, bottom - 文本类
text-top, text-bottom - 上标下标类
sub, super - 数值百分比类
20px, 2em, 20%, ...
我们先来看看数值百分比类,这个类其实可以分为数值类和百分比类这两个小类。
这两个小类的共性:
- 都带数字
- 都支持负值(在CSS中,支持负值的属性有margin, letter-spacing, word-spacing, vertical-align)
- 行为和表现一致
数值类就是在 baseline 对齐基础上上下偏移对应数值大小,如 vertical-align: 1px; 就是在基线的基础上上移1px。而vertical-align 的百分比值是相对于 line-height 计算的,例如某元素的line-height 是20px, vertical-align:25% 相当于设置vertical-align: 5px。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> p{ background-color: #ccc; } #p2{ line-height: 100px; } #span1{ vertical-align: 10px; } #span2{ vertical-align: 100%; } </style> </head> <body> <section> <p id="p1"> <img src="./123.jpg" /><span id="span1">xxxxxxx</span> </p> <p id="p2"> <img src="./123.jpg" /><span id="span2">xxxxxxx</span> </p> </section> </body> </html>
效果如下:
vertical-align 起作用的前提
vertical-align 只能应用于inline水平以及‘table-cell’元素。
inline水平元素主要有:
- inline:<img>, <span>, <strong>, <em>,...
- inline-block:<input>, <button>, ...
'table-cell' 元素有:
- table-cell:<td>
但是下面方式:
display:更改元素的显示水平
css 声明间接更改元素的显示水平,如下面代码
<style> p{ background-color: #ccc; } #img1{ float: left; vertical-align: middle; } </style> <section> <p> <img id="img1" src="./123.jpg" /><span>xxxxxxx</span> </p> </section>
效果如下,图片浮动了,其display水平变成block,因此 vertical-align 失效了。
再如:
<style> p{ background-color: #ccc; } #img1{ position:absolute; vertical-align: middle; } </style> <section> <p> <img id="img1" src="./123.jpg" /><span>xxxxxxx</span> </p> </section>
效果如下图,文字跑到图片后面去了,此时图片display水平也是block。
下面还有一个vertical-align 失效的例子。
<style> p{ height: 300px; text-align: center; background-color: #ccc; } #img1{ vertical-align: middle; } </style> <section> <p> <img id="img1" src="./123.jpg" /> </p> </section>
效果如下,图片没有垂直居中。
其实不是vertical-align: middle没起作用,而是太短,不够居中,将行高设为容器高度值就可以解决了。
p{ height: 300px; line-height: 300px; text-align: center; background-color: #ccc; }
实现个数不定文字内容和图片垂直居中对齐
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> div{ background-color: #ddd; 800px; margin: 0 auto; } li{ list-style: none; margin-bottom: 10px } span{ display: inline-block; 400px; vertical-align: middle; } img{ vertical-align: middle; } </style> </head> <body> <div> <ul> <li> <span>一段文字,一段文字,一段文字,一段文字一段文字,一段文字</span> <img src="./123.jpg"/> </li> <li> <span>一段文字,一段文字</span> <img src="./123.jpg"/> </li> <li> <span>一段文字,一段文字</span> <img src="./123.jpg"/> </li> </ul> </div> </body> </html>
vertical-align 与 line-height
vertucal-align 和 line-height 之间的关系很明确,即“朋友”关系。如下面几个例子
- vertical-align 的百分比值是相对于 line-height 计算的
- 只要出现内联元素,这对好朋友就会出现。
例如容器高度不等于行高的例子,就是vertucal-align 和 line-height 搞的鬼。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> #div1{ line-height: 32px; background-color: #ccc; } #div1 > span{ font-size: 24px; } </style> </head> <body> <div id="div1"> x<span>文字x</span> </div> </body> </html>
效果如下
我们可以看到,容器高度为35px, 行高是32px,左右两边的x大小不相同。为什么会这样呢?有一个很关键的点,那就是font-size: 24px 是设置在span元素上的,导致外部div与span字体大小有出入。
由于受line-height:32px 影响,这两个内联盒子高度都是32px,我们应该知道,对字符而言,font-size 越大字符的基线越往下,因为文字默认全部是基线,所以当字号大小不一样的两个文字在一起时,就会发生上下位移,如果位移距离足够大,就会超过行高的限制,而导致意料之外的容器高度,如下图。
搞清楚原因,我们就能找到解决办法了。关于隐匿文本节点和内联盒子,可以参见上一篇。
方法一:我们可以让隐匿文本节点和后面span元素字号一样大
<style> #div1{ line-height: 32px; font-size: 24px; background-color: #ccc; } #div1 > span{ font-size: 24px; } </style>
方法二:改变垂直对齐,比如顶部对齐,这样就不会有参差位移。
<style> #div1{ line-height: 32px; background-color: #ccc; } #div1 > span{ font-size: 24px; vertical-align: top; } </style>