1、基础

  • 线类 ,如 baseline( 默认值)、top、middle、bottom
  • 文本类,如 text-top、text-bottom
    • vertical-align的文本类属性值。示例
      • vertical-align:text-top:盒子的顶部和父级内容区域的顶部部对 。
      • vertical-align:text-bottom:盒子的低部和父级内容区域的底部部对 。
      • 内容区域: Firefox/IE浏览器文本选中的背景区域,或者默认状态下的内联文本的背景区域 。

image.png

  • 上标下标类(不会改变当前元素的文字大小)
    • vertical-align:super:提高盒子的基线到父级合适的上标基线位置。
    • vertical-align:sub: 降低盒子的基线到父级合适的下标基线位置。
  • 数值百分比类 ,如 20px、2em、20%等。——根据计算值的不同,相对于基线向上或向下偏移,无兼容性问题 。举例
    • vertical-align默认按照基线对齐,基线的定义是字母x的下边缘,vertical-align:baseline等同于vertical-align:0。(ex:字母x的高度The height of the letter “x”)
    • margin 和 padding是相对于宽度计算的,line-height 是相对于 font-size 计算的,而这里的 vertical- align 属性的百分比值则是相对于 line-height 的计算值计算的, 设某元素的 line-height 是 20px,那么此时 vertical-align:-25%相当于设 vertical-align:-5px。 (因为目前网页布局

2、深入

1)vertical-align的作用范围

  • vertical-align仅作用于内联元素/display:table-cell的元素,即vertical-align 属性只能作用在 display 计算值为 inline、inline-block,inline-table 或 table-cell 的元素上;
  • 支持的元素:等内联元素 ,vertical-align - 图2
  • 浮动定位和绝对定位会使元素块状化,从而使vertical-align失去作用;

2)单行垂直居中方法(line-height+vertical-align/父元素table-cell+vertical-align)
例子1:对于单行文本,line-height设置多少,行高就是多少?举例

  1. <div class="box">
  2. <span>line-height: 32px</span>
  3. </div>
  4. box { line-height: 32px; }
  5. .box > span {
  6. font-size: 20px;
  7. }

image.png
要避免“空白幽灵节点”的干扰,设置元素的display:inline-block,创建一个独立的“行框盒子”;

  • 幽灵空白元素:幽灵空白元素,在每个“行框盒子”前面有一个宽度为 0 的具有该元素的字体和行高属性的看不见的“幽灵空白节点” 。
  • 虽然就效果而言,table-cell元素设置vertical-align垂直对齐的是子元素,但是其作用的并不是子元素,而是 table-cell元素自身。就算 table-cell的子元素是一个块级元素,也一样可以让其有各种垂直对齐表现。

3) vertical-align与line-height——凡是line-height起作用的地方,vertical-align一定起作用
例子1:不同字号文字高度超出行高—示例

  1. <div class="box">
  2. x<span>文字x</span>
  3. </div>
  4. box { line-height: 32px; }
  5. .box > span {
  6. font-size: 24px;
  7. }

image.png
原因:对字符而言,font-size 越大字符的基线位置越靠下,因为文字默认全部都是基线对齐 ,所以当字体大小不一样的两个文字在一起的时候, 此就会发生上下位移,如果位移足够大,就会超过行高的限制,而导致出现意料之外的高度。
解决办法: 1)让空白幽灵节点和span中的字体一样大; 2)vertical-align:top
例子2:图片底部空隙问题:任意一个块级元素 ,里面若有图片,则块级元素高度基本上都要比图片的高度高。 示例

  1. 展开代码
  2. CSS
  3. <div class="box">x
  4. <img src="http://p0.meituan.net/scarlett/1035e65cb96755aadf9caf310244d8089034.jpg" />
  5. </div>
  6. .box {
  7. width: 280px;
  8. outline: 1px solid #aaa;
  9. text-align: center;
  10. }
  11. .box > img {
  12. height: 96px;
  13. }

image.png
原因: 默认基线对齐,替换元素的基线是元素的下边缘,字体x的基线也是下边缘,字体x往下的行高产生的多余的间隙就嫁祸到图片下面,让人以为是图片产生的间隙,实际上是“幽灵空白节点”、 line-height 和 vertical-align 属性共同作用的结果。
解决办法:示例
1)图片块状化:图片设置display: block;
2)容器line-height足够小:设置容器line-height:0;
3)容器font-size足够小:设置容器font-size:0;
4)图片设置其他vertical-align属性;
例子3:内联特性导致margin失效, 示例
image.png
原因:非主动触发位移的内联元素是不可能跑到计算容器外面的,导致图片的位置被 “幽灵空白节点”的 vertical-align:baseline 给限死了;
例子4:相同 display 计算值相同尺寸却对不齐不对 (inline-block与baseline) 示例

  1. 展开代码
  2. CSS
  3. .dib-baseline {
  4. display: inline-block;
  5. width: 150px; height: 150px;
  6. border: 1px solid #cad5eb;
  7. background-color: #f0f3f9;
  8. }
  9. <span class="dib-baseline"></span>
  10. <span class="dib-baseline">x-baseline</span>

image.png
原因:vertical-align 属性的默认值 baseline 在文本之类的内联元素那里就是字符 x 的下边缘,对于替换元素则是替换元素的下边缘。但是,如果是 inline-block元素 ,则规则要复杂了:一个inline-block元素,如果里面没有内联元素,或者overflow不是visible,则该元素的基线就是其margin地边缘;否则其基线就是元素里面最后一行内联元素的基线;
4)vertical-align:middle—-近似垂直居中示例

  1. 展开代码
  2. CSS
  3. <div class="box">
  4. <img src="http://p0.meituan.net/scarlett/1035e65cb96755aadf9caf310244d8089034.jpg">x
  5. </div>
  6. .box {
  7. width: 280px;
  8. line-height: 128px;
  9. background-color: #f0f3f9;
  10. font-size: 16px;
  11. }
  12. .box img {
  13. height: 96px;
  14. vertical-align: middle;
  15. }

image.png
绿线为容器的垂直中心线,红线为图片的垂直中心线,发现两条线是有一定间隙的,fontSize越大越明显;
原因:

  • 设置内联元素vertical-align:middle: 是指内联元素的的垂直中心点和行框盒子基线往上 1/2 x-height处对齐 (换句话说,vertial-align:middle 可以让内联元素的真正意义上的垂直中心位置和字符 x 的交叉点对齐。)
  • 基本上所有的字体中,字符 x 的位置都是靠下一点儿的,font-size 越大偏移越明显,这才导致默认状态下的 vertial-align:middle 实现的都是“近似垂直居中”。

    3、总结

    1)top/bottom对齐看边缘/行框盒子;baseline/middle和x字符打交道
    2)一个基于vertical-align属性的水平垂直居中弹框(大小不固定的弹窗始终居中的效果)示例
    https://codepen.io/shehaodan/pen/XBqpRz ```javascript 展开代码 CSS

.container { position: fixed; top: 0; right: 0; bottom: 0; left: 0; background-color: rgba(0,0,0,.5); text-align: center; font-size: 0; white-space: nowrap; overflow: auto; } .container:after { content: ‘’; display: inline-block; height: 100%; vertical-align: middle; } .dialog { display: inline-block; vertical-align: middle; text-align: left; font-size: 14px; white-space: normal; }

```