CSS垂直定位属性:vertical-align

参考文章:
Vertical-Align: All You Need To Know

MDN:vertical-align

张鑫旭:字母’x’在CSS世界中的角色和故事

张鑫旭:我对CSS vertical-align的一些理解与认识

张鑫旭:CSS深入理解vertical-align和line-height的基友关系

张鑫旭:CSS vertical-align的深入理解(二)之text-top篇

一 概览

本文从微观层面讲述vertical-align的工作原理,工作环境。并整理了用vertical-align实现文本和图片居中的方法。

二 涉及内容概念

1. 顶线,中线,基线,底线
分别对应英文作业本的四条线:

图1-四条线

基线最为重要,行内元素就躺在这条线上。且行内元素默认基线和父元素(行框)基线对齐。

中线的定义为:中线位于基线的上方,与基线的距离为小写字母x高度的一半(即0.5ex),而ex同font-size相关,大部分浏览器认为1ex = 0.5em(em同样也是相对单位,不是绝对单位),因此会将基线以上1/4em处作为中线来对齐。

2. 内容区
顶线和底线包裹的区域。

内容区由字体大小和字数决定,跟行高半毛钱关系没有

给一个没有设置行高的行内元素设置背景,可以看到其内容区:


图2-内容区

3. 行高
简单讲就是行内元素所占的高度。

学术点就是内容区加上以内容区为中心上下对称扩展的空白区域,也就是上下行基线之间的距离。

4. 行距(行间距)
上一行的底线和下一行的顶线之间的距离。

也就是:(上一行行高-内容区高度)/2+(下一行行高-内容区高度)/2

5. 行内框(inline-box)
用例子来说明:

<p class="two-p">
        <span class="two-span span1">我有自己的行内框</span>
        <span class="two-span span2">我也有自己的行内框</span>
        <span class="two-span span3">我也有自己的行内框</span>
</p>
图3-行内框和行框

虽然三段话在同一行内,但是它们各有各的一块“区域” —— 一个长方体,将他们各自包裹起来,这些长方体在行内不一定对齐。

这些长方体就是行内框。

每个行内元素有自己的行内框。

文本行内框高度=行高=内容区+行距

图片行内框=内容区+padding+border+margin (也就是它自己的盒子模型)


图4-没有加内外边距的图片的行内框
.img{
    margin: 10px;
    padding:10px;
}
图5-加上内外边距之后图片的行内框

6. 行框(line-box)
图3中的行框就是灰色背景的那块区域。

可见,行框的任务就是包裹同一行行中的行内框,方便页面的渲染。

可以想象成一个大的快递箱,这个快递箱把很多大小不一的小快递箱包裹起来。那么这些大快递箱可以很整齐地摆放,而不是一对小快递箱随意堆在一起。

行框的高度由行内框最高点和最低点决定。

图4-行内框和行框

7. 包含框
一个个行框组成了包含框。

三 vertical-align的值

top:元素顶部(行内框)和行框顶部对齐
bottom:元素底部和行框底部对齐

baseline:默认值,元素基线和行框(父元素)基线对齐
sub:下标
super:上标
text-top:元素行内框顶部和行框(父元素)文本(不是图片或其他)的顶部对齐,这里的文本应该指的是行框中没有添加任何样式的匿名文本(自己实验得出,如有误请指正)
因为这个属性用的比较少,所以这里就没有整理了,感兴趣的同学可以自己看一下张鑫旭的另一篇文章:CSS vertical-align的深入理解(二)之text-top篇
text-bottom:元素底部和父元素文本的底部对齐,这里文本同上
middle:元素的中垂点和父元素的基线向上半个“x”距离的那根线对齐,垂直居中的中流砥柱
<length>:具体高度,比如10px
<percentage>:百分比,相对基线偏移行高的百分比。比如,行高100px,偏移10%,即相对基线向上偏移10px

四 行框的基线怎么确定

1. 主要知识点:

  1. 行内元素基线对齐是和父元素也就是行框的基线对齐。
  2. 行框的基线会为了满足布局,行高最小化等需求而改变位置。
  3. 可以通过匿名行内元素“x”来确定父元素基线位置。

2. 详细内容:

正如每个行内元素自己的基线,行框也有自己的基线。

行框的基线由所有行内元素的基线来确定。

行框的基线位置不是固定不变的,是会改变的。

行框需要其基线来满足一些需求,比如,垂直对齐,使行高最小化等等。当它遇到这些需求的时候,就会调整基线的位置。

举个例子,现在有三个行内元素:

<div class="one">
    <span class="icon taller"></span>
    <span class="icon shorter"></span>
    xxx
</div>
图5-行框的基线

行框的基线相对于匿名行内元素“x”的最低点是不对的,它永远和“x”元素的最底点对齐。

现在,给长条的绿色长方形加上一个样式:vertical-align:middle

图7-长条形垂直居中后行框的基线

讲道理,我们设置了长条形的样式,应该是长条形下移而不是另外两个行内元素上升呀。

如果从微观来看,长条形撑起了行框的高度。行框内已经没有任何空间给它移动了。可以理解为行高总是尽可能的小。

上面也说过,行框的基线会为了满足一些需求而移动。

所以行框就把基线往上移,移到长条形的中垂线再向上1/2个“x”的距离。(1/2“x”的距离下面会讲到)这样子行高就不会增大。

如果长条形不变,短条形设置vertical-align:middle

图8-短条形垂直居中后行框的基线

移动的就是短条形而不是其他两个行内元素了。因为这样做行高的增加是最小的。

所以为什么有时候想要让某一个元素行内居中,改变的是其他行内元素的位置呢?有答案了。

五 莫名的空隙

1. inline-block元素底部的空隙

比如,在一个div中放入一张图片,会发现图片的底部和div的底部不是贴合的,有一个空隙:


图9-图片底部有空隙

同样地,写网页导航的时候,设置每个li的样式为display:inline-block,这时候会发现,导航的下面也有一条空隙:

图10-导航条底部也有空隙

这条空隙其实是行内元素基线和底线之间的空隙。

想要去掉这条空隙,要么把基线移走,要么直接让它消失。

比如,元素设置样式:display:block:变成非行内元素,基线就不复存在了:

图11-图片设置为块元素

又比如,元素设置样式:vertical-align:middle/text-top/text-bottom/bottom,将父元素的基线往上移:

图12-设置元素的vertical-align为middle

再比如,在元素内写入文本,让父元素的基线上移:


图13-元素内写入文本让父元素基线上移

六 用vertical-align实现垂直居中

1. 图片(inline-block元素)居中

只需把父元素的行高设置为想要的高度,再给图片添加样式vertical-align:middle即可。

<div class="container" style="line-height:200px;">
    <img src="../static/images/img1.jpg" style="vertical-align:middle;">
</div>

图14-图片居中

需要注意的是这里的“居中”并不是严格意义上的居中,这里的“居中”是:图片的中垂线和父元素基线向上1/2个“x”字母的高度对齐。

2. 单行文本居中

<div style="line-height:200px;">
    <p >xxx</p> 
</div>
图15-单行文本居中

3. 多行文本居中

把多行文本当成图片处理(对内可以设置宽高,对外是内联元素)

<div class="three">
      <p class="three-p">
          <span class="three-one">third</span><br>
          <span class="three-two">third</span><br>
          <span class="three-two">third</span>
      </p>
</div>
<style>
    .three{
        line-height: 200px;
    }
    .three-p{
        display: inline-block;
        line-height:1.4em;
        vertical-align: middle;
    }
</style>
图16-多行文本居中

七 直通地心的大坑:vertical-align:middle 失效

有一次进行测试的时候,发现vertical-align:middle失效了!代码如下:

<html>
    <head>
    </head>
    <body>
        <div class="container" style="line-height:200px;">
            <img src="../static/images/img1.jpg" style="vertical-align:middle;">
        </div>
    </body>
</html>

什么?!!!代码完全没有问题啊?!!!!以前都是这样写的!!!!为什么不行了!!!

一个上午都在debug,就是找不到问题在哪里!

后来一哥们觉得,既然代码都是一样的,那就是标准的问题了。

于是,在文档前面加了一句<!DOCTYPE html>

居中了!!!!!

原来跟混杂模式还是标准模式有关!

所以使用这个属性一定要使用标准模式!

如果想要兼容旧浏览器,请加上一个空格来撑开行高:

<div class="container" style="line-height:200px;">
    <img src="../static/images/img1.jpg" style="vertical-align:middle;">&nbsp;
</div>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容