参考文章:

深入了解CSS的line-height属性

Vertical-Align: 你需要知道的所有事【译】

Vertical-Align: All You Need To Know

1、什么是行间距或者行高(line-height)

line-height是指文本行基线间的垂直距离。

1.1、顶线,中线,基线,底线

从上到下分别是顶线,中线,基线,底线。vertical-align的四个属性top,middle,baseline,bottom就是与这四条线有关。

1.2、行高,行距,半行距

  • 行高是指上下文本行基线间的垂直距离。(上图中两条红线间的垂直距离)
  • 行距是指一行底线到下一行顶线的垂直距离。(第一条粉线和第二条绿线间的垂直距离)
  • 半行距就是行距/2。(图中可以看出,半行距=(行高-字体size)/2 )

1.3、内容区,行内框,行框

  • 内容区:顶线和底线包裹的区域(字体的size)
  • 行内框:在没有其他因素影响的时候(padding等),行内框等于内容区。而设定行高时行内框高度不变,半行距分别增加/减少到内容区的上下两边(深蓝色区域)行框(line box)。(字体size不变,修改行高就是修改行距)
  • 行框:行框高度等于本行内所有元素中行内框最大的值(以行高值最大的行内框为基准,其他行内框采用自己的对齐方式向基准对齐,最终计算行框的高度),当有多行内容时,每行都会有自己的行框。

1.4、line-height的设置

百分比方式设置

<body>
121212
<p>121212</p>
</body>
body{
font-size:16px;
line-height:120%;
}
p{
font-size:32px;
}

line-height的百分比(120%)和body的字体大小(16px),被用来计算(16*120=19.2),这个值会被层叠下去的元素所继承。

补充

p{
font-size:32px;
line-height:60px;
padding:10px
}

最终盒模型

盒模型中,内容(不是上文说的内容区,上文的内容区是顶线与底线间的区域)的高度等于line-height的值。为什么会有margin?浏览器默认P的上下margin是1em,设置了P的font-size是32px,所以1em=32px。上下margin就是32px。

长度方式(px)设置

<body>
121212
<p>121212</p>
</body>
body{
font-size:16px;
line-height:20px;
}
p{
font-size:32px;
}

值normal

<body>
121212
<p>121212</p>
</body>
body{
font-size:16px;
line-height:normal;
}
p{
font-size:32px;
}

body的line的line-height是22px,所以normal等于1.375

p的line-height:32px*1.375=44px(normal并不是精确的等于1.375)

纯数字

就是将normal改为一个想要的准确数字。

1.5、各种BOX

<body>
<p>这个<em>强调</em> 元素为行内元素</p>
</body>
body{
font-size:16px;
line-height:1.5;
}
p{
font-size:32px;
padding:10px;
}

containing box

p就是一个containing box,包含了其他boxs。

inline box

在段落内,有一系列的inline box,inline box不会让内容成块显示,而是排成一行。“强调”是一种inline box,“这个”,“元素为行内元素”为一种匿名inline box。

line box

多个inline box组成line box,多个line box组成containing box。

Content Area

Content Area是围绕着文字的一种看不见的box,高度取决与font-size

inline box与line-height

font-size:32px,line-height:48px,行间距=48px-32px=16px,半行间距=8px。

半行间距会用在Content Area的顶部和底部。



这里inline box的高度就是line-height。inline box包着Content Area

但是,当line-height小于font-size。line box的高度还是line-height,所以line-box的高度小于Content Area的高度,Content Area会溢出line-box。

inline box 与line box

line box的高度取决于他内部最高的inline box。

2、vertical-align

vertical-align是用来对齐内联级元素的。设置为以下display属性的元素,它们都被认为属于内联级元素。inlineinline-block or **inline-table **(本文中不涉及此种情况):

inline内联元素基本上是包裹文本的标签。

inline-block内联块元素则如它们的名字所示:拥有内联特性的块元素。他们可以有width和height(可能是由自己的内容定义),以及padding、border和margin。

内联级元素彼此紧挨着放在一行中。一旦有更多的元素被放置到当前行中,一个新的行将会在它下面创建。所有这些行有所谓的“行框”,行框中包含所有的内容。不同大小的内容意味着不同高度的行框。在下面的插图中,行框的顶部和底部都是用红线表示的。

在行框中,元素的vertical-align属性是负责垂直对齐的。那么,到底元素垂直对齐的参照物是什么?

参照物:父元素的基线和外边缘

看看元素的基线和行框的外观:

inline元素

三行并排的文本。行框的顶部和底部边缘用红线表示,字体的高度由绿线表示,基线由一条蓝线表示。在左边,有一个line-height设置为与字体font-size大小相同高度的文本,绿线和红线重叠在一条线上。在中间,line-height是字体的两倍大。在右边,line-height是字体大小的一半大。

内联元素(display:inline)的外边缘与其行高的顶部和底部边缘对齐,行高可以小于字体的高度。所以,行框就是上面的图中的红线。

内联元素的基线是字符放置的位置线(字母x底部所在的水平线),即图中的蓝线。粗略地说,基线是在字体1/2高度的下面的某个地方。

inline-block元素

inline-block因为已经有宽和高,可能存在多行,每行都有自己的基线和行框,所以会比较特殊。

上图中,最外层是div,里面分别是三个inline-block的span,黄色为border,绿色为padding,蓝色为content area(一个span,其中有一个字母“C”)。左边的inline-block的span的内容(span)是一个正常文档流元素。中间的inline-block的span还额外加了overflow: hidden。右边的inline-block的span包含一个流外的span(但内容区域有一个高度)(译者注:流内的元素必须是普通文档流(normal flow)中的元素,流外的元素必须是浮动或绝对定位的元素以及根元素。)。蓝线为每个inline-block的span的基线。内联块元素的外边缘是其margin框的顶部和底部边缘,即图中的红线。

内联块元素(上图三个inline-block的span)的基线取决它包含的内容是否在文档流中:

  • 在流内内容的情况下,内联块元素的基线是正常流中最后一个内容元素的基线(左边的例子)。对于这最后一个元素,它的基线是根据它自己的规则找到的。
<div class="demo1">
x<span>
x<span style="display:inline-block;height:30px;width:100px;background-color:blue">x</span>
x
</span>
</div>
.demo1 span{
display:inline-block;
background-color:silver;
height:90px; }



灰色背景的元素内部有三个子元素,两个“x”,一个span。元素的基线就是最后一个正常流元素(“x”)的基线。

修改元素的长度,使其内容出现多行:

最外面的X怎么也跟着移动了?这涉及行框基线的移动,下文细说。

  • 在流内内容但内联块元素有overflow:hidden属性的情况下,基线是内联块元素margin框的底部边缘(例如在中间的图)。

    修改上面的例子样式:
.demo1>span{
display:inline-block;
background-color:silver;
height:90px;
width:100px;
margin:10px;
overflow:hidden;
}



通过最外面的x大致知道行框的基线位置,就是内联块元素的下外边距的地方,也是内联块元素元素的基线位置。

一开始此处有疑惑:内联块元素元素的基线跑到了下外边距处,那么元素里面的内容不应该以这条基线做定位吗?群里问了大佬,内联块元素已经设了宽高,可能有多行(即使只有一行),每行有各自的行框,然后又根据规则定位了,跟内联块元素的基线已经没有关系。

  • 在流外内容的情况下,基线是内联块元素margin框的底部边缘(例如在右边)。
<div class="demo1">
x<span>
<span style="display:inline-block;height:30px;width:100px;background-color:blue;">x</span>
</span>
</div>
.demo1>span{
display:inline-block;
background-color:silver;
height:90px;
width:100px;
}

加上浮动

<div class="demo1">
x<span>
<span style="display:inline-block;height:30px;width:100px;background-color:blue;float:left">x</span>
</span>
</div>

行框的基线是可变的

当使用vertical-align时,基线放置在哪里可能是最令人疑惑的部分。它需要满足vertical-align的值和行框的高度等所有条件。基线的位置犹如是方程中的一个自由参数。

行框的基线是看不见的,但你可以使它很容易看到。只要在文本行的开头添加一个字符,像我增加了一个“X”的字母。如果这个字符不以任何方式对齐,它将默认地坐在基线上。

围绕着行框的基线的部分(绿线),我们可以称其为文本框。文本框可以简单地被认为是行框内的内联元素,没有任何对齐。文本框的高度等于它的父元素的字体大小。因此,文本框只围住了行框内的无格式文本。由于这个文本框是绑在基线上的,当基线移动时它将移动。(注:此文本框在W3C规范中称为“strut(支柱)”)

vertical-align的值

1)将元素的基线,参照父元素的基线对齐

baseline:元素的基线与父元素的基线对齐。

sub:元素的基线偏移到父元素的基线之下。

sup:元素的基线偏移到父元素的基线之上。

:元素的基线相对于父元素的基线偏移了一个百分比(该百分比是对比元素自身的line-height计算得出)。

:元素的基线相对于父元素的基线偏移了一个绝对长度。

2)将元素的中心点,参照父元素的基线对齐

middle:将元素的顶部和底部之间的中心点,对齐父元素的基线之上x-height的1/2之处(x-height为字母x的字符高度)。

3)将元素的外边缘,参照父元素的文本框对齐

text-top:将元素的顶部边缘,对齐到父元素的文本框的顶部边缘。

text-bottom:将元素的底部边缘,对齐到父元素的文本框的底部边缘。

4)将元素的外边缘,参照父元素行框的外边缘对齐

top:元素的顶部边缘对齐到父元素的顶部边缘。

bottom:元素的底部边缘对齐到父元素的底部边缘。

基线的移动

如果一行中有一个高个的元素占据了整行的高度,那么vertical-align对它没有影响。它的顶部和底部没有空间让它移动。为了满足行框基线的对齐方式,行框的基线必须移动。矮个元素设置了vertical-align: baseline。在左边,高个元素设置了vertical-align: text-bottom。在右边,高个元素设置了vertical-align: text-top。你可以看到右边的基线跳起来了。

(左)将两个元素放在一行中并设置vertical-align ,它们会使得行框的基线移动到符合它俩的对齐规则之处,然后行框的高度也会随之调整。(中)添加第三个元素,不超越行框的边缘,既不影响行框的高度,也不影响基线的位置。(右)添加第三个元素,如果它超出了行框的边缘,行框的高度和基线调整。在这种情况下,我们的前两个元素也会跟着发生变化。

内联级元素底部的小间隙

列表项坐在基线上。下面的一点空间,是文本的基线以下预留的depth(在W3C规范中,一个字体的基线以上称为characteristic height,基线以下称为depth)。想要去掉这个depth空隙,有解决的办法吗?只要移动基线的位置就可以,例如通过设置列表项目vertical-align: middle

水平垂直居中

<div class="box">
<div class="content">
自适应垂直居中
</div>
</div>
html{
height:100%;
}
body{
height: 100%;
width: 100%;
}
.box{
display:inline-block;
text-align: center;
width:50%;
height:50%;
background-color:#e1e3cd;
overflow:hidden;
}
.box:after{
content:"";
display:inline-block;
height:100%;
vertical-align:middle;
}
.content{
vertical-align:middle;
background-color:silver;
display: inline-block;
width: 50%;
height:50%;
}

要将content水平垂直居中定位在box里,利用vertical-align是其中一种方法。原理是:vertical-align:middle(将元素的顶部和底部之间的中心点,对齐父元素的基线之上x-height的1/2之处(x-height为字母x的字符高度)。),content肯定是要垂直居中的,那只能修改行框的基线位置(注意:不是修改box的基线,box具有宽高,它里面的内容可能会有多行,每行有各自的行框,box的基线已经不会影响内容的布局,但是box的基线还是会受里面内容的影响(内联块元素的基线是正常流中最后一个内容元素的基线)),使其位于box的垂直中心位置。修改行框的基线,只要在box内加一个高度为100%的空元素,然后设置vertical-align:middle,添加的元素已经占满整个行框高度,而只要移动行框的基线,就可以满足定位规则,所以行框的基线就被移动到box垂直中心位置。content再按规则对齐到行框基线上就可以了。

CSS中line-height与vertical-align的更多相关文章

  1. CSS中设置height:100%无效的解决方案

    在网页设计中有时会设置某个DIV或者TABLE的高度自适应,即元素的高度充满父元素的高度.一般使用设置CSS  height:100%来实现.但是当元素层级嵌套比较深的时候,设置该属性并不能得到应有的 ...

  2. CSS中的height与line-height的区别

    <p class='text'>高与行高的区别</p> 那么我要想让这些字上下居中那么可以用宽度和行高控制 .text{ height:25px; line-height:25 ...

  3. css中 出现height为100%失效的原因及解决方案

    我们都知道需要给html和body标签设置了高度height:100%之后,再给内部的div设置height:100%的时候,内部div的高度100%才会起到作用.这是由于:%是一个相对父元素计算得来 ...

  4. What is Vertical Align?

    https://css-tricks.com/what-is-vertical-align/ ************************************************* CSS ...

  5. 真正的能理解CSS中的line-height,height与line-height

    https://blog.csdn.net/a2013126370/article/details/82786681 在最近的项目中,常常用到line-height,只是简单的理解为行高但并没有深层次 ...

  6. css中的width,height,属性与盒模型的关系

    这段话很容易记住盒模型: css中盒子模型包含属性margin.border.padding.content,他们可以把它转移到我们日常生活中的盒子(箱 子)上来理解,日常生活中所见的盒子也具有这些属 ...

  7. 【CSS中width、height的默认值】

    对于初学者来说,CSS中的width.height的默认值是很神奇的,因为经常看到如下这样的代码:明明只给一个#father标签(红色的div)设置了一个width,为啥它在浏览器中显示出来是有一个固 ...

  8. css中height 100vh的应用场景,动态高度百分比布局,浏览器视区大小单位

    css中height 100vh的应用场景,动态高度百分比布局,浏览器视区大小单位 height:100vh 一些只能vw, vh才能完成的应用场景: 1. 场景之:元素的尺寸限制 vw vh 主要是 ...

  9. CSS中width和height与盒子模型的关系

    盒子模型 css中盒子模型包含属性margin.border.padding.width与height,他们可以把它转移到我们日常生活中的盒子(箱子)上来理解,日常生活中所见的盒子也具有这些属性,所以 ...

  10. 深入了解css的行高Line Height属性

    什么是行间距? 古时候我们使用印刷机来出来文字.印刷出来的每个字,都位于独立的一个块中. 行间距,即传说中控制两行文字垂直距离的东东.在CSS中,line-height被用来控制行与行之间垂直距离. ...

随机推荐

  1. Strange fuction

    Strange fuction Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...

  2. 交换知识 VLAN VTP STP 单臂路由

    第1章 交换基础 1.1 园区网分层结构 层次 作用 出口层 广域网接入 出口策略 带宽控制 核心层 高速转发 服务器接入 路由选择 汇聚层 流量汇聚 链路冗余 设备冗余 路由选择 接入层 用户接入 ...

  3. web前端学习路线和步骤

    H5+全栈工程师  (学习下列技术可以加QQ: 1416 7596 61)第一阶段:初级入门阶段基本功 1.HTML入门 Windows概述.浏览器概述.HTML简介.HTML标签详解.前端开发工具概 ...

  4. mac链接linux终端,shell脚本发布代码

    项目的业务需求:从mac端直接连上linux服务终端,并发布相关的代码 一.使用ssh链接上linux服务端 1.cd ~/.ssh 2.vi config,按照下面的内容配置config文件,然后: ...

  5. JavaScript系列----一切皆是对象

    1.判断对象类型 1.1.typeof 运算符 首先要认识到,typepof是一个运算符,其运算需要一个参数,返回值是参数的类型. typeof使用方法 typeof parameter //使用方法 ...

  6. socket阻塞IO流程图

    单线程 多线程

  7. ImageAnimator类方法(动画设计)

    ImageAnimator类常用方法如表所示. 表    ImageAnimator类常用方法 方法 说明 Animate 将多帧图像显示为动画 CanAnimate 返回一个布尔值,该值指示指定图像 ...

  8. 异步 HttpContext.Current实现取值的方法(解决异步Application,Session,Cache...等失效的问题)

    在一个项目中,为了系统执行效率更快,把一个经常用到的数据库表通过dataset放到Application中,发现在异步实现中每一次都会出现HttpContext.Current为null的异常,后来在 ...

  9. protobuf/android 交叉编译笔记

    protobuf 交叉编译笔记 目标是使用 android ndk 的工具链编译出 android armeabi-v7a 可用的 protobuf 库. 交叉编译环境配置 windows 平台 下载 ...

  10. JavaScript学习笔记(十)——高阶函数之map,reduce,filter,sort

    在学习廖雪峰前辈的JavaScript教程中,遇到了一些需要注意的点,因此作为学习笔记列出来,提醒自己注意! 如果大家有需要,欢迎访问前辈的博客https://www.liaoxuefeng.com/ ...