css - 行高

line-height行高

取值:px | em | rem | 百分比 | 纯数字 | normal | inherit

设置给:块、行内、行内块

应用给:文本

继承:块、行内、被转换为行内块的容器元素(比如转换为行内块的span、div)。不继承行高的元素:img、原生的行内块(input、textarea等)。

层叠性:按照css层叠特性,行高可以被覆盖

作用:设置容器里每一行文本的高度,使每一行具有上下间距。比如设父元素行高100,则它包含的每一行文本的最终高度都是100px,如果它包含的是子元素,则根据继承规则使子元素继承行高,子元素所包含的文本的每一行也等于100px。

boxes模型

要理解行高,首先需要了解boxes模型

1.content area box

你可能以为只要为不同font-family的文本设定相同font-size,那么这些不同风格的文本就会得到一个相同的高度,可实际上并不是这样,就连两个同样风格的字体,它们的高度都可能不一样,比如以下两个字母的高度就不一样:

不同风格的字体有支持中英文的,甚至有可能一套字体可以支持其他国家的文字。对于字体设计师来说,设计一款字体时必须考虑这套字体中最高字符的高度,然后把这个高度固定为这套字体的最小高度。这样上图中的x的高度就会出现一些间距以保证这个x和g是一样高的。我们把填充了间距的、包裹住文本的空间称为content area。

以微软雅黑为例,如果你将其font-size设为1px,那么这风格的字体在浏览器上显示的高度是4px,如果设为font-size:0,则文字不可见,于是可以得出微软雅黑的最小高度是4px,也即,设定的font-size实际上是在文字默认的高度下对文字进行增高。chrome浏览器的默认字体高度是16px,在16px的设定下,微软雅黑的高度是21px,当你设这种字体为font-size:17px后,那么其高度会在微软雅黑的最小高度的基础上继续变高(文字具体多高取决于浏览器的算法),这导致content area也跟着font-size的增加而增高。下图可以看出该风格的字体用css设置其高度为90px,文本的content area在该字体默认的最小高度的情况下增高,同时使content area也增大。该风格的字体在浏览器的90px下大概会变大到120px。

在使用浏览器默认行高、父元素不设置高度、一行上只有纯文本的情况下,当你用鼠标左键选中浏览器中的文本后,你可以看到conten area的高度,这个高度才是文字的真实高度。

2.inline box

inline box是指每一行上的各种纯文本、行内、行内块元素的外围被隐形的inline box包含,inline box并不在html中显示,但它们确实存在。因为这些元素有inline box包装,所以每个文本、行内、行内块才能在一行上显示。也即,一行上并列的各种元素都可以看成是一个一个的inline box。考虑一下以下的html有几个inline box?

<div>
    中文<i>Element</i> United Kingdom  a country in western
</div>

第一行有纯文本中文两字,这是一个inline box,而i标签是一个inline box,i标签后的文本也是一个inline box,换行的另外两行各自是一个inline box,一共有五个inline box。

3.line box

每个inline box组合成一行就变成了一个line box,

4.containner box

行高的计算规则

每一行的文本都有行间距,分上半间距和下半间距,文本的content area+其上下间距就=行高。行高计算规则为:

css设置的line-height - content area height = 间距,间距÷2=conten area的上下间距,浏览器用上下间距对content area的顶部和底部进行填充,导致inline box被撑大。当content area的上下有了填充后,整个inline box就像有了上下padding一样,使得每一行看上去有一定的距离,保持了每一行的整洁有序。
line box与行高

line box的高度就是一行的最终高度,而这个高度是采用的该行上最高的那个inline box。但又有两种情况:
1.如果采用的最高的那个inline box存在行高,则该line box的最终高度 = 你设定的该元素的行高。
这种情况必定是发生在文本上,因为只有文本才存在行高。比如一行上最高的就是文本,该文本的高度是200px,而为其设定的行高却是100px,那么该行最终高度=100px
2.如果采用的最高的那个inline box没有行高,则该行最终高度=该inline box的最终高度。
比如一行上最高的是图片,图片不是文本,不存在行高,但它的高度是一行上最高的,那么该行最终高度 = 图片的高度

以下是一个父元素包含一个x文本和一张图片,该父元素只有一行,没有第二行,所以可以把父元素看成是单个的line box。

上图,图片的高度 = 100px,文本x的高度=16px,一行上图片最高,line box高 = 100px

上图:父元素的行高 = 110px,图片高 = 100px,line box高 = 110px

上图:文本font-size = 120px,图片高 = 100px,父元素行高 = 110px,,则line box的高度 = 行高 110px,文本溢出

行高对元素的影响

1.无内容

如果元素不包含任何内容,则行高无效,因为行高来自于元素所包含的文本,没有文本则没有行高,即便像块、行内块可以设置高度,但如果它们不包含文本,就不会有行高。

2.非块元素

行高是否起效,首先就要观察一行上是否存在文本。如果有文本则应用到文本上。如果没有文本,就要观察该行上是否存在可以在一行上并列显示的元素,比如行内块(包括非原生的行内块)和img元素,如果存在这两种元素且该行上 没有明确显示的文本时,则该行的行高会应用到该行的隐形x上,使隐形x顶底部填充间距,这些元素就在垂直方向上以隐形x的基线垂直对齐。

上图:一行上没有文本,只有图片,父元素行高100px应用到了隐形x的顶底部

上图:一行上没有文本,只有转换为行内块的div,父元素行高100px应用到了隐形x的顶底部

上图:一行上没有文本,只有行内块的input,父元素行高100px应用到了隐形x的顶底部

3.块元素

如果一行上没有文本且只有子块元素,那么由于子块元素独占一行,所以跟它同一行的隐形x是不存在的,没有隐形x,就没有行高。这样,父元素包含块元素时,父元素的高度就等于块元素的高度,不存在行高。

上图:一行上没有文本,只有子块元素,则该行不存在行高,父元素高度=子块元素的高度

上图:子块元素继承行高100px,行高100px应用到它包含的每一行文本上。父元素高度=200px

行高溢出的规则

1.块、行内块元素

当line box取该行上最高的inline box的行高时,具有行高间距的必然是文本,如果文本高于行高,那么多出的文本和文本的间距可能会溢出在外面。当行高小于文本高度导致的溢出发生在块、行内元素上,它们的第一行文本的行高上边距和最后一行文本的行高下边距会溢出在外面。

2.行内元素

当行高小于文本高度导致的溢出发生在行内元素时,如果它包含的是直接的文本,则文本会在行高限定的区域内被挤压,如果它包含的是子行内元素,且子行内元素高于父行内元素,则子行内元素会溢出在外面。

解决文本、文本间距溢出

浏览器默认的行高normal是一个数字倍数,是基于inline box的高度的倍数,而所有的元素的line-height默认值都是normal,所以使用倍数数字的行高要优于直接写绝对单位的行高,绝对单位是定死的高度,当它小于文本的高度时,文本、文本行高间距就会溢出。如果必须设定更高的行高,可以考虑设行高为纯数字倍数,这样可以保证元素不溢出。

行高对垂直对齐的影响

行高对兄弟元素之间的垂直对齐有影响,首先需要知道应用了行高的文本的inline box的四条线,文本具有行高或不具有行高,其四条线中的顶线和底线会有不同。当文本具有行高时,其四条线如下

文本的inline box的顶线=文本的行高上边距的顶部
文本的inline box的中线=文本的中线
文本的inline box的基线=文本的基线
文本的inline box的底线=文本的行高下边距的底部

line box的最终高度只取最高的那个inline box,但一行上的各个inline box的高度并不会统一。比如一行上文本x的行高是30px,x旁边的其它文本行高是110px,而图片的高度是120px,两个文本的inline box的高度并不会随着line box的高度而改变。现在我们假设一个line box上有两个文本x,文本是16px,第一个x的行高是30px,则行高半间距是7px,第二个x的行高是110px,则它的半间距是47px。现在在每个x的后面插入两个图片,图片的高度分别是100px和120px。结合垂直对齐可以看出以下的结果:

顶线对齐(vertical-align:top)

top表示inline box的顶线与line box的顶线对齐。第一个x的上边距为7px,其顶线在上边距顶部,其顶部与line box的顶线对齐,第二个x的上边距是47px,所以第二个x的上边距顶部与line box对齐。

底线对齐(vertical-align:bottom)

bottom表示inline box的底线与line box的底线对齐。

基线对齐(vertical-align:baseline)

baseline表示inline box的基线与line box的基线对齐。line box的基线= x的底线,图片的inline box会以自身的底线与x的底线对齐,所以当图片往上移动以便和x的底线对齐时,x的下边距就留在了下面,使整个containner被撑大

中线对齐(vertical-align:middle)

middle表示inline box的中线与隐形x的中线对齐。

行高的继承性

块、行内、被转换为行内块的容器元素(比如转换为行内块的span、div)都会继承行高。像原生的行内块:input、textarea并不继承行高。所以当你在一个块元素里包含一个input,设块元素的行高100,行高间距只在input顶底部进行填充,但input如果继承了行高,那么input内的空白文本区域就应该相应的增高,但实际上input内部空白文本区域并不会变高。原生行内块元素虽然不继承行高,但如果你直接对它们设置行高,那么它们会应用到自身所包含的空白文本区域,使输入的每一行文本具有行高。

字符下沉

当line box的高度是选择的该行中行高最高的那一个文本的inline box的时候,该行中所有包含文本的inline box就会下沉,这包括隐形x同样会下沉。文本下沉后,隐形x的顶线、中线、基线、底线就会跟着往下移,而其它inline box的四条线跟隐形x有密切的关系,这直接导致了以隐形x的四条线垂直对齐的inline box向下偏移。

下图中的line box的高 = 该行中最高的inline box(该inline box的行高为100px,包含了文本x),造成该行所有文本的inline box下沉,黄色线是文本x下沉后的中线,当输入框以中线与隐形x的中线对齐后,其垂直位置是向下偏移的。

上面的例子在浏览器上可能不太容易看出垂直居中的问题,因为只有细微的差别。下面为文本x设置行高30px,这只比输入框高大概10px左右,line box会选择文本的inline box的行高作为其最终高度,可以看出文本下沉后,输入框的middle对齐已经不是垂直居中的效果了

解决办法是设font-size:0,这样隐形x的inline box的高度就是0,此时隐形x就没有高度了,它上下填充的间距就是整个line box的高度了,中线就是该行的中心线,行上的其它inline box就会以自身的中线与隐形x的这条线对齐了。但如果父元素设为了font-size:0,那么它的后代元素中的文本肯定就不可见了,如果你需要其它包含在子标签里的文本在该行上显示出来,你只需要单独再为这些文本设置font-size即可,那么就算父元素设置了font-size:0,只要用子元素将文本包含起来,为子元素设置字号,那么文本依然会选择16px的字号,不会导致子元素内的文本不可见。

* {
    margin: 0;
    padding: 0;
    font-size: 16px;
    font-family: 方正兰亭超细黑简体;
}

.wrapper {
    color: #fff;
    line-height: 30px;
    font-size: 0;
    background: #2f2f2f;
    background: #006031;
}

.wrapper span{
    vertical-align: middle;
}
<div class="wrapper">
    x <!--隐形x-->
    <span>span</span>
    <input type="text"/>
</div>

行高的几种取值(行高不能是负数)
div { line-height:20px;} 
div { line-height:120%; } 
div { line-height:normal; } 
div{  line-height:2.2;} 
div {  line-height: inherit; } 

行高可以直接写在font属性的字号大小之后,用/隔开,表格式必须是:fontsize/lineHeight 空格 字体名字

div {  font: 16px/20px 微软雅黑; } 
div {  font: 16px/120% 微软雅黑; } 
div {  font: 16px/normal 微软雅黑; } 
div {  font: 16px/2.2 微软雅黑; }
div {  font: 16px/inherit 微软雅黑 } 

行高取值的分类

1.固定取值 【 长度单位(px、pt、cm、inherit)】

比如当前元素的font-size是16px,其行高设为200%,则行高为16*2=32px,它包含的每一行的行高都会固定为32px,如果其中某行的font-size为100px,由于行高已经固定为32px,所以该行行高保持32px不变,而文本会溢出。用js获取该行的height和line-heigh可以发现都是32px。

2.自适应取值【rem、%、纯数字、normal】

表示当前元素及其它包含的每一行中的inline box都用它们自己的font-size*纯数字=各自的行高,比如当前元素的font-size是16px,其行高设为2,则行高为16*2=32px,它包含的每一行的行高都会用它们自身的font-size*纯数字,如果其中某行的font-size为100px,则该行的行高为100*2=200px,父元素整体高度也会自适应这种改变。

默认行高

浏览器都有一个默认的行高。取值:normal。

文本的四条线(行高的额外内容)

无论怎样设置行高,行高的高度都是两行文本的基线垂直距离。

顶线:从一段文本中顶部最高处拉出的一条假想的线

底线:从一段文本中底部最低处拉出的一条假想的线

中线:与顶线和底线距离相等的一条假想的线

基线:从一段文本中最短的那个文字处拉出的一条假想的线

doctype声明与行高(行高的额外内容)

如果你的html文档没有DOCTYPE声明,css样式包括行高都会出你意料。规范的html文档必须要有DOCTYPE声明

 

前端学习总目录

最新文章

  1. javascript 学习一(概述+基本语法)
  2. 蜘蛛纸牌存档修改——python3.4.3
  3. jquery获取表单的值
  4. [Bhatia.Matrix Analysis.Solutions to Exercises and Problems]ExI.3.6
  5. STL之优先队列
  6. 高级数据结构(树状数组套主席树):ZOJ 2112 Dynamic Rankings
  7. hdu Find a way
  8. gnome3 no launcher
  9. 我的第二个独立开发的邮箱类App—“简邮”(支持QQ、雅虎、阿里云、Outlook)
  10. Pycharm设置去除显示的波浪线
  11. 动态参数(*args,**kwargs),命名空间和作用域,global和nonlocal,函数的嵌套
  12. golang语言中os/signal包的学习与使用
  13. svn 回退/更新/取消至某个版本命令详解【转】
  14. Java设计模式之十一种行为型模式(附实例和详解)
  15. Eclipse Git提交代码,多了一个“工程同名的文件夹”,找不到解决办法!!!
  16. Web层的Controller代码逻辑
  17. shell的uniq命令
  18. Java泛型中extends和super的理解
  19. vim 打开中文乱码
  20. CSS3 animation动画

热门文章

  1. [004] - JavaSE面试题(四):JavaSE语法(2)
  2. github在不同电脑上协同开发
  3. gos-log高性能大日志检索中台
  4. 第六篇--MFC美化界面
  5. PHP 接受提交变量过滤类
  6. vulnhub-DC:5靶机渗透记录
  7. K8S系列第九篇(持久化存储,emptyDir、hostPath、PV/PVC)
  8. Vue+SpringBoot前后端分离中的跨域问题
  9. 学习Android Jetpack? 入门教程和进阶实战这里全都有!
  10. zookeeper查看启动状态报错:Error contacting service. It is probably not running.