一次内联元素错位引发对line-height的思考

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

内容简介:作者:李一睿line-height 对于一个前端小可爱来说,应该是一个会经常碰面的老朋友了。可是有一天,我突然发现自己好像对他没那么了解,他也没有外表看起来的那么简单。事情的经过是这样的……

作者:李一睿

line-height 对于一个前端小可爱来说,应该是一个会经常碰面的老朋友了。可是有一天,我突然发现自己好像对他没那么了解,他也没有外表看起来的那么简单。

事情的经过是这样的……

在偶然一次工作中,我写了这样的模板:

<div>
    <span class="name">重大疾病险</span>
    <span class="tip">保额每月可累计</span>
</div>
复制代码
div{
    font-family: "PingFang SC";
}
.name{
    line-height: 20px;
    font-size: 20px;
}
.tip{
    display: inline-block;
    line-height: 20px;
    font-size: 14px;
}
复制代码

两个相邻的内联元素,字体一大一小,行高相同,由于第二段文字需要有字多情况就自动去下一行的效果,所以第二个 spaninline-block 我畅想的结果是,两个 span 高度都是 20px, div 高度也是 20px,多么完美。但结果往往不近人意……

一次内联元素错位引发对line-height的思考

div 的高度怎么是 28??

一次内联元素错位引发对line-height的思考 一次内联元素错位引发对line-height的思考

再一看子元素,一个 28 一个 20??

  • 疑问1:难道是 line-height 对行内元素不生效??

    然而规范告诉我,对于非替代的 inline 元素,它用于计算行盒(line box)的高度。

  • 疑问2:既然生效了,为什么审查元素看着是 28,不是 20 呢?

    对于文本来说,存在一个内容区域(content area)。你可以理解为,用光标选中这行文字时带背景的区域。他同时受 font-family 和 font-size 的影响。就算是相同的字号,如果字体不同,‘你所看到’的高度也是不一样的,同学们可以自己尝试一下。这里强调你所看到的,也就是我们这里的 28px,它其实是这个文本内容区的高度,而内容区的高度并不是真正的高度,也就是说,它不会影响这个元素真正的尺寸,也不会撑起父元素的高度,所以只是一个你看起来的高度。而对于行内元素来说,真正影响它高度的就是 line-height

    在这里,我们可以通过改变他们的 font-family 来证实一下。

    div{
          font-family: "HelveticaNeue";
      }
      .name{
          line-height: 20px;
          font-size: 20px;
      }
      .tip{
          display: inline-block;
          line-height: 20px;
          font-size: 14px;
      }
    复制代码
    一次内联元素错位引发对line-height的思考 一次内联元素错位引发对line-height的思考 一次内联元素错位引发对line-height的思考

    可以看到,更改了字体之后, .name 的高度由28变成了24, .tip 由于是 inline-block 所以高度没变,但是父 div 的高度依然是28px,说明content area并不会影响父元素的真实高度。

  • 疑问3:那如何看到它真正的高度?

    你可能也发现了,第二个 span 是 inline-block ,它的高度就是 20px,那我们将第一个 span 也设置成 inline-block 来看一下。

    一次内联元素错位引发对line-height的思考

    果然,它的高度终于变成了我们期望的 20px。

    那我们再来看一下父元素 div 的高度:

    一次内联元素错位引发对line-height的思考

    !!怎么还是 28px??

  • 疑问4:两个子元素都已经是 20px 了,为什么父元素还是 28px?

    这里先声明两个问题:

    inline-block
    

    接着回到我们的问题,仔细看上图,可以发现,两个高度都是 20px 的子元素,上下都有一定的间隙;再仔细看,发现它俩没对齐,红色背景的靠上,粉色背景的靠下,它俩之间稍微有些错位。就是这些,让我们的父元素被撑成了 28px。那它们又是从哪里来的呢?

    既然是对不齐导致父元素被撑高了,那 CSS 中相关对齐的属性,我们很容易想到是 vertical-align ,难道是它搞得鬼?那我们试着改一下它们的 vertical-align

    一次内联元素错位引发对line-height的思考

    vertical-align:top ,上面对不齐了

    一次内联元素错位引发对line-height的思考

    vertical-align:middle ,好像跟之前差别不大……

    虽说这些属性值都没能让他们对齐,但可以发现确实是与它有关的,可能是我们哪里使用不当,影响了这个属性?那我们就去了解一下 vertical-align 是怎么对齐的,起初我们不设置的时候,会取它的默认值: baseline —— 基线对齐。

    内联元素默认是基线对齐的,而基线就是指行框盒子中字母'x' 的下边缘:

    一次内联元素错位引发对line-height的思考

    诶??再仔细看看我们之前对不齐的那张图,你会发现,虽然元素没对齐,但是文字下端是对齐的,这不就是正常的基线对齐吗!这下就说的通了。

    划重点!!

    行内元素的对齐方式默认是基线对齐,也就是都与 x 的下边缘对齐。这两个 span 的高度是一样的,都是 20px,然而重点就在于它们的字体大小不一样。而文本在如果设置了 line-height ,是会基于 line-height 居中的,也就是说,它们分别在各自高度相同框框中居中,但由于字号大小不一样,所以文字底部是对不齐的,但他们又需要基线对齐,所以它俩开就必须要错位一下。

    这里引用一下鑫旭大神的图:

    一次内联元素错位引发对line-height的思考
  • 疑问5:那这是不是就说明,我们把两个元素的行高设置成不一样,就可以不错位把父元素撑高了?

    一次内联元素错位引发对line-height的思考

    这里我们分别给两个 span 设置与自己字体大小一样的行高:20px 和 14px,可以看到它俩已经没有向外错位了,但是父元素的高度并没有如期,还是 28px。怎么回事?难道还有别的东西再影响它?

    你猜对了,但这是个我们看不见的东西。引用一下张鑫旭大神的叫法——幽灵空白节点。

    “幽灵空白节点”是内联盒模型中非常重要的一个概念,具体指的是:在 HTML5 文档声明 中,内联元素的所有解析和渲染表现就如同每个行框盒子的前面有一个“空白节点”一样。这 个“空白节点”永远透明,不占据任何宽度,看不见也无法通过脚本获取,就好像幽灵一样, 但又确确实实地存在,表现如同文本节点一样,因此,我称之为“幽灵空白节点”。

    既然看不见,那我们可以拿一个看的见的 x 字符来假装它。

    <div>
          <em>x</em>
          <span class="name">重大疾病险</span>
          <span class="tip">保额每月可累计</span>
      </div>
    复制代码
    div{
          font-family: "PingFang SC";
      }
      em{
          display:inline-block; /*为了审查元素看到的不是content area*/
          font-style:normal;
      }
      .name{
          line-height: 20px;
          font-size: 20px;
      }
      .tip{
          display: inline-block;
          line-height: 20px;
          font-size: 14px;
      }
    复制代码
    一次内联元素错位引发对line-height的思考

    这个 'x' 字号和行高都没有设置,字号是继承下来的 20px,元素行高默认是 1.x(1.x 倍的 font-size),具体数值还有待研究,但绝对是 >1 的,由图可见,什么都没有设置的情况下,这个 'x' 的高度就是 28px,也就代表着,那个幽灵空白节点的高度就是 28px。

    那我们将幽灵空白节点的行高设小一些不就好了?可是这个幽灵节点,看不见摸不着,怎么设啊。别忘了, line-heigt 是可继承性的,我们给父 div 设置 line-heigt ,幽灵节点自然就会继承。

如何解决

明白了上述的疑问以及原理,接下来就看下怎么解决这个问题。

解决一

我们可以给父 divline-height 设置一个很小的值

div{
    line-height: 5px;
    font-family: "PingFang SC";
}
em{
    display:inline-block; /*为了审查元素看到的不是content area*/
    font-style:normal;
}
.name{
    line-height: 20px;
    font-size: 20px;
}
.tip{
    display: inline-block;
    line-height: 20px;
    font-size: 14px;
}
复制代码
一次内联元素错位引发对line-height的思考 一次内联元素错位引发对line-height的思考

这样,幽灵节点的行高就只有 5px,父元素行高 20px,没毛病。但这个方法还不够完美,因为你需要想一下这个很小的值……

解决二

当 line-height 设置为一个无单位的数值时,表示是某倍的font-size。

div{
    line-height: 1;
    font-family: "PingFang SC";
}
em{
    display:inline-block; /*为了审查元素看到的不是content area*/
    font-style:normal;
}
.name{
    line-height: 20px;
    font-size: 20px;
}
.tip{
    display: inline-block;
    line-height: 20px;
    font-size: 14px;
}
复制代码

给父元素设置 line-height 为1,这样,子元素高度都是自己的 font-size ,包括幽灵空白节点。这样就不会再有人无意间撑高父元素了。当然,除非你的幽灵空白节点继承下来了一个很大的 font-size, 这点你得明白。

一次内联元素错位引发对line-height的思考 一次内联元素错位引发对line-height的思考

解决三

既然行高可以与 font-size 有关,font-size 也是可继承的,那我们将父元素的 font-size 设为 0

div{
    font-size: 0px;
    font-family: "PingFang SC";
}
em{
    display:inline-block; /*为了审查元素看到的不是content area*/
    font-style:normal;
}
.name{
    line-height: 20px;
    font-size: 20px;
}
.tip{
    display: inline-block;
    line-height: 20px;
    font-size: 14px;
}
复制代码
一次内联元素错位引发对line-height的思考 一次内联元素错位引发对line-height的思考

可以看到,我们模仿的那个幽灵节点已经没有了,宽高都是 0 了,父元素的高度也自然就回到了 20px。


以上所述就是小编给大家介绍的《一次内联元素错位引发对line-height的思考》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

Artificial Intelligence

Artificial Intelligence

Stuart Russell、Peter Norvig / Pearson / 2009-12-11 / USD 195.00

The long-anticipated revision of this #1 selling book offers the most comprehensive, state of the art introduction to the theory and practice of artificial intelligence for modern applications. Intell......一起来看看 《Artificial Intelligence》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

SHA 加密
SHA 加密

SHA 加密工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具