深入理解行高 - 以“支柱”概念为核心

栏目: Html · 发布时间: 4年前

行高概念

  • 行高类似于我们上学单线本,单线本是一行一行,线与线之间的距离就是行高,

    深入理解行高 - 以“支柱”概念为核心

  • 基线 :字母X下边缘的位置,微软雅黑完美压线,各个字体略有不同

  • 中线 :基线+1/2字母x的高度的位置

    可见,中线的位置与font-size有关

  • 行高 :上下文本行的基线间的距离,由line-height属性值确定

    为什么需要两行?其实一行也是有行高的,由两行这个概念上的定义可以确定一行的行高

  • 内容区 :底线和顶线包裹的区域,是一种围绕文字的盒子,大小与 font-sizefont-family 相关

    在页面中选中文字的时候的蓝色背景就是content-area,实际上就是em-box

    行内元素display:inline可以通过background-color属性显示出来

  • 行距 :一行底线到下一行顶线的垂直距离,行距默认情况下会均分到内容区的两侧

    在simsun字体下,内容区高度等于文字大小值:行间距=行高 - font-size,为了降低难度,以下的demo都是simsun字体,新宋

    其他字体,行间距 = 行高 - 内容区大小

  • 行内盒(inline box) :即是行内框,行中的每个元素都会生成一个内容区,内容区的大小由 字体和字号 确定,将行距/2分别应用到内容区的顶部和底部,其结果就是该元素的行内盒

    将line-height的计算值减去font-size的 计算值 ,这个值就是行距,这个值可能是个负值,

  • 行盒(line box) :即是行框,行盒是指一个虚拟的矩形盒, 默认情况 下行盒高度等于本行内所有元素的行内盒最大的值

    一行上垂直对齐时以行高值最大的行内盒为基准,其他行内盒采用自己的对齐方式向基准对齐,最终计算行盒的高度 ,还会收到vertical-align属性的影响

    每一行只能有一个行盒,行内嵌套宽度由内容撑开,仍然只一个行内盒而已

注意:

  • 浏览器渲染的时候,会比实际的font-size要大,30px的字体大小,内容区本应是30px高度,但是被渲染成了40px 深入理解行高 - 以“支柱”概念为核心

    字体在基线之上和之下的高度和深度被假定为包含在字体内的特性。(更多细节,参见CSS3。)

    因为默认值normal比较小,由于字体的原因,同一个元素内容区的高度很可能比行内盒的高度高,

    对于高清屏,测量值会受到WIN10 默认放大的影响,可以自行换算,实际上是准确的

  • 在实际开发中,处理大量文本的时候,建议把行高设置成比字体大小大, 默认行高是font-size 的1.5倍左右 ,各浏览器差异大

line-height

属性值

normal:

  • 让用户代理设使用值为一个基于元素字体的“合理”值。该值与< number >意义相同。我们推荐 normal 的使用值在1.0到1.2之间。计算值为 normal

    normal具体的表现是数值,具体的数值由用户代理决定,在1-1.3之间

    chrome:微软雅黑,1.32,/ sinsum,1.14

    firefox: 微软雅黑,1.32 / sinsum,1.144

    计算方法:font-size:100px; container.clientHeight/100

< length >

  • 指定长度用于行盒高度计算。负值非法。

< number >

  • 本属性的使用值为此数值乘以本元素的字号。负值非法。

< percentage >

  • 本属性的计算值为此百分比乘以元素的字号计算值。负值非法。

inherit

  • 对于某些可替换元素,可能line-height的默认值不是normal,需要使用inherit重置

示例

  • 下面例子中的三条规则的行高结果相同:

    div { line-height: 1.2; font-size: 10pt }    /* number */ 
    div { line-height: 1.2em; font-size: 10pt }    /* length */ 
    div { line-height: 120%; font-size: 10pt }    /* percentage */复制代码
  • 继承结果不同, < number > 的话指定值,然后子元素根据自身的font-size计算line-height

  • < number >和< percentage >继承父元素line-height的计算值(根据父元素自身的font-size计算)

可替换行内元素

  • 在此文中,请简单理解为图片

  • line-height 属性值没有意义,对图片没有任何影响

不可替换行内元素

  • 在此文中,请简单理解为文本

  • line-height 指定用于计算行盒高度的高度

  • 即使行高设定的比内容区高度还要小(内容区大小取决于字体大小),行内盒的高度仍然是由line-height决定

    内联元素的实际高度是由line-height决定的 ,这和我们学习的块元素的盒子模型完全不同

    对于行内盒而言可以做到撑开父级的只有一个属性:line-height,其他的盒模型部分都是不相关的,包括垂直方向上的margin、border、padding、content,全都没有办法撑开父元素的高度

    也就是说:内联元素在垂直方向上的位置只会受到:font-size,line-height,vertical-align的影响

  • 行内盒的位置会受到字体的影响因为,行距 = line-height - font-size ,这个行距其实就行内盒的边框

  • 文字会默认在行高中垂直居中显示 ,这是因为行距默认等分在内容区的两边

  • 注意:内容区的大小会影响横向的排列,也就是

    深入理解行高 - 以“支柱”概念为核心

    text line-height为0,无法改变行盒的高度,但是font-size变化会影响横向的排列

    height是由内容撑开的,font-size变化,平分线也跟着变化

    使用simsun字体,并且line-height为1,可以把内容区看作行内盒的边框,也就是上图中粉色的背景区域

块级容器元素

  • 一般情况下, line-height 指定该容器内 行盒最小高度

    与heigt属性值做区分,height值一旦指定,容器的高度就不会在发生变化,因此子元素可能 溢出

  • 验证: line-height 指定该容器内 行盒最小高度 ,而不是该容器的最小高度,区别于 min-height

    <div id='container'> </div>复制代码
    #container{     
      position: relative;     
      line-height: 100px;     
      font-size:36px;     
      font-family: 'simsun';    
      background-color: rgb(200, 200, 200);   
    }复制代码
  • 此时容器是没有高度,但是如果指定的是min-height,则容器会保持这个高度

  • 那么指定行盒的最小高度要怎么理解呢?为了解决这个疑惑,我们需要引入一个重要的概念: 支柱

支柱 strut

  • 对于块容器元素而言,line-height属性值的另一个重要的意义在于 被支柱继承

  • line-height是继承属性,因此line-height任何情况下都有默认值。line-height的默认值是normal,那么line-height的计算值就是该元素的 字体字号 *normal

  • font-size也是可继承的,因此font-size任何情况下都有默认值

    该值同样是由用户代理决定的,以chrome为例,默认的font-size为16px

  • 因此:对内容由行内级元素组成的块容器元素而言

    • 就如同每个行盒以一个具有该块容器元素 字体字号 以及 line-height 属性的 零宽度 行内盒开始一样。我们称此虚构盒为“支柱 Strut ”。(该命名灵感源于Tex。)

    • 根据上述说明,默认情况下支柱的高度是:16px*normal

    <div id='container'>   <span>xxx</span> </div>复制代码
    #container{   
      /* 块容器的行高:16*normal */   
      /* 同时也是支柱的行高 */   
      background-color: rgb(200, 200, 200); 
    } 
    span{   
      /*span的行高小于支柱:12*normal */   
      font-size:12px;   
      background-color: white; 
    }复制代码

    深入理解行高 - 以“支柱”概念为核心

  • 可以看到,容器的高度比span的高度还要高,这是因为容器此时被 支柱 给撑开了

  • 因此,对于 非空 的块容器元素而言,可以认为 line-height 指定了容器的最小高度

  • 如果容器是空的,即使指定了line-height容器也是没有高度的,说明容器的高度不是line-height指定的,而是被支柱继承了之后撑开的

  • 更准确的理解:容器的line-height属性,设置了支柱的高度,当支柱存在时,可以确定行盒以及容器的最小高度

支柱出现的条件

  • 如果容器标签体为空则不会出现支柱

  • 如果有文字或者图片

    • 不论文字的行内盒font-size为何值,都存在支柱

    • 图片高度无论是什么值,存在支柱

  • 支柱的本质:不是html排版的空白符,而是浏览器默认添加的隐匿文本节点,空白符

行盒的高度

  • 对于块容器而言,容器的高度是由行盒撑开的,能够撑开行盒只有两种:

    • 对于不可替换行内元素而言,是其 line-height 值,而不是内容区

      还要考虑vertical-align属性

    • 对于可替换行内元素而言,是其 外边距盒 的高度

      还要考虑vertical-align属性

  • 验证: 撑开父元素的是不可替换行内元素的 line-height ,而不是内容区

    #container{   
      line-height:0px;   
      font-size:0px;   
      font-family: 'simsun';   
      background-color: rgb(200, 200, 200); 
    } 
    span{   
      line-height:36px;   
      background-color: white; 
    }复制代码

    深入理解行高 - 以“支柱”概念为核心

  • 可以看到父元素还是被撑开了,此时支柱的行高和字号都是0,也就是说父容器的高度被span的line-height属性决定的,这一点适用于所有不可替换行内元素,也包括支柱

确定基线和中线

  • 为了方便理解,以下所有demo中我们根据以下的标准进行探讨:

    • 以一个 显式的支柱 为基准

    • 以最简单的结构,不要考虑行内元素的嵌套,不要考虑字体影响,不要考虑表格元素

      一个行盒可以由块级盒产生,也可以由行内级盒产生,它描述了一行行内元素的渲染方式

      统一采用simsun字体

      表格元素表现差异很大,另外讨论

    <div id='container'>   
      <span id='strut'>llx</span>   
      <span id='text'>textYyx</span>   
      <img src="./img/img2-middle.jpg" alt="123"/>
    </div>复制代码
    #container{    
      position: relative;    
      line-height: 100px;    
      font-size:36px;    
      font-family: 'simsun';    
      background-color: rgb(200, 200, 200);  
    }  
    #text{    
      line-height: normal;    
      font-size:36px;    
      position: relative;    
      background-color: pink;    
      vertical-align: baseline;  
    }  
    #strut{    
      position: relative;    
      font-size:inherit;    
      line-height: inherit;    
      background-color: pink;    
      border:1px greenyellow solid;  
    }  
    img{    
      position: relative;    
      line-height:normal;    
      font-size:36px;    
      width: 50px;    
      height: 50px;    
      vertical-align: baseline;  
    }复制代码

    深入理解行高 - 以“支柱”概念为核心

    为了更加直观的理解,css的属性都是显式写出,支柱相关属性都是继承于块容器

    开启相对定位,用伪元素标识出元素的平分线,容器的平分线为红色,文本的平分线为绿色,图片的平分线为黑色

  • 首先: 我们可以认为 父元素的基线就是支柱的基线 ,因为支柱的所有性质都继承于父元素,假设在支柱内有一个字母x,那么这个字母x的下边缘就是基线

    基线永远在小写字母x的下边缘

  • 确定基线的偏移,不论 支柱 是否是行内盒的最高盒,基线总是向上偏移半行距。基线的偏移 直接 受到父元素 line-height 属性值的影响:

    • 支柱 是行内盒中最高的时候,基线向上偏移半行距

    深入理解行高 - 以“支柱”概念为核心

    • 当支柱的高度小于行内最高盒的时候,支柱撑起父容器的 角色 被最高盒代替,最高盒成为 新的支柱但是 基线的位置仍然是在 初始支柱 的小写字母x的下边缘

    深入理解行高 - 以“支柱”概念为核心

  • 基线的偏移 间接 受到父元素 font-size 属性值的影响, 本质上是影响了行距 ,因为 行距 = line-height - font-size

  • 基线的位置再加上1/2 x的高度就是中线的位置

  • 中线也是 相对绝对性 ,永远在基线上方1/2字母x的高度处,因此也会受到 line-heightfont-size 的影响

vertical-align

  • 此属性影响 行内级元素 生成盒在行盒内的垂直定位。

属性

  • baseline :把盒的基线同父盒的 基线 对齐

    父盒x的下边缘

  • middle :把盒的 垂直中点 同父盒的 中线 对齐

    中线:基线加上父盒一半的 x-height

  • text-top :使元素的顶部与父元素的 顶线 对齐。

  • text-bottom :使元素的底部与父元素的 底线 对齐。

  • top :使元素及其后代元素的顶部与整行的顶部对齐

    注意:不是父盒的顶线

  • bottom :使元素及其后代元素的底部与整行的底部对齐

    注意:不是父盒的底线

  • 上述值仅相对于父行内元素或父块容器元素的支柱 Strut 有意义。

  • 在上面的定义中,对行内不可替换元素而言,用于对齐的行内级盒是高度为 line-height 的盒( 包括行内盒的内容区)

    只有基线对齐是依赖于行内盒的基线,其他全都是根据line-height盒

    假设行内盒的line-height为0,那么对于该行内盒而言用于对齐的就是 平分线 的位置,与字体大小完全无关,但此时baseline还是根据字体的基线

  • 对于其他所有元素,用于对齐的行内级盒是 外边距盒

起作用的前提

  • 行内级元素

结语

  • 现在我们准确的捕捉到了基线的所在,这样理解vertical-align属性就很简单了,只要找准支柱,主要属性都试一遍,也就理解了90%了。剩下的主要是一些边际情况和实际运用,我会在下一篇文章讲解

  • 顺便吐槽以下,掘金的代码块太不友好了,从md复制代码的时候总是忽略排版,又要一个个敲空格,不知有没有比较好的解决办法


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

程序员的呐喊

程序员的呐喊

[美]Steve Yegge / 徐旭铭 / 人民邮电出版社 / 2014-5-1 / 45.00元

《程序员的呐喊》的作者是业界知名的程序员—来自google的steve yegge,他写过很多颇富争议的文章,其中有不少就收录在这本书中。本书是他的精彩文章的合集。 《程序员的呐喊》涉及编程语言文化、代码方法学、google公司文化等热点话题。 对工厂业界的各种现象、技术、趋势等,作者都在本书中表达了自己独特犀利的观点。比如java真的是一门优秀的面向对象语言吗?重构真的那么美好吗?强......一起来看看 《程序员的呐喊》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

SHA 加密
SHA 加密

SHA 加密工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具