内容简介:作者:李一睿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; } 复制代码
两个相邻的内联元素,字体一大一小,行高相同,由于第二段文字需要有字多情况就自动去下一行的效果,所以第二个 span
是 inline-block
我畅想的结果是,两个 span 高度都是 20px, div 高度也是 20px,多么完美。但结果往往不近人意……
div 的高度怎么是 28??
再一看子元素,一个 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; } 复制代码
可以看到,更改了字体之后,
.name
的高度由28变成了24,.tip
由于是inline-block
所以高度没变,但是父div
的高度依然是28px,说明content area并不会影响父元素的真实高度。 -
疑问3:那如何看到它真正的高度?
你可能也发现了,第二个 span 是
inline-block
,它的高度就是 20px,那我们将第一个span
也设置成inline-block
来看一下。果然,它的高度终于变成了我们期望的 20px。
那我们再来看一下父元素
div
的高度:!!怎么还是 28px??
-
疑问4:两个子元素都已经是 20px 了,为什么父元素还是 28px?
这里先声明两个问题:
inline-block
接着回到我们的问题,仔细看上图,可以发现,两个高度都是 20px 的子元素,上下都有一定的间隙;再仔细看,发现它俩没对齐,红色背景的靠上,粉色背景的靠下,它俩之间稍微有些错位。就是这些,让我们的父元素被撑成了 28px。那它们又是从哪里来的呢?
既然是对不齐导致父元素被撑高了,那 CSS 中相关对齐的属性,我们很容易想到是
vertical-align
,难道是它搞得鬼?那我们试着改一下它们的vertical-align
:vertical-align:top
,上面对不齐了vertical-align:middle
,好像跟之前差别不大……虽说这些属性值都没能让他们对齐,但可以发现确实是与它有关的,可能是我们哪里使用不当,影响了这个属性?那我们就去了解一下
vertical-align
是怎么对齐的,起初我们不设置的时候,会取它的默认值:baseline
—— 基线对齐。内联元素默认是基线对齐的,而基线就是指行框盒子中字母'x' 的下边缘:
诶??再仔细看看我们之前对不齐的那张图,你会发现,虽然元素没对齐,但是文字下端是对齐的,这不就是正常的基线对齐吗!这下就说的通了。
划重点!!
行内元素的对齐方式默认是基线对齐,也就是都与 x 的下边缘对齐。这两个 span 的高度是一样的,都是 20px,然而重点就在于它们的字体大小不一样。而文本在如果设置了
line-height
,是会基于line-height
居中的,也就是说,它们分别在各自高度相同框框中居中,但由于字号大小不一样,所以文字底部是对不齐的,但他们又需要基线对齐,所以它俩开就必须要错位一下。这里引用一下鑫旭大神的图:
-
疑问5:那这是不是就说明,我们把两个元素的行高设置成不一样,就可以不错位把父元素撑高了?
这里我们分别给两个
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; } 复制代码
这个 'x' 字号和行高都没有设置,字号是继承下来的 20px,元素行高默认是 1.x(1.x 倍的 font-size),具体数值还有待研究,但绝对是 >1 的,由图可见,什么都没有设置的情况下,这个 'x' 的高度就是 28px,也就代表着,那个幽灵空白节点的高度就是 28px。
那我们将幽灵空白节点的行高设小一些不就好了?可是这个幽灵节点,看不见摸不着,怎么设啊。别忘了,
line-heigt
是可继承性的,我们给父div
设置line-heigt
,幽灵节点自然就会继承。
如何解决
明白了上述的疑问以及原理,接下来就看下怎么解决这个问题。
解决一
我们可以给父 div
的 line-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; } 复制代码
这样,幽灵节点的行高就只有 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, 这点你得明白。
解决三
既然行高可以与 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; } 复制代码
可以看到,我们模仿的那个幽灵节点已经没有了,宽高都是 0 了,父元素的高度也自然就回到了 20px。
以上所述就是小编给大家介绍的《一次内联元素错位引发对line-height的思考》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- MySQL中一个双引号错位引发的血案
- 面试过程中的失配与错位,大家怎么看?
- ios12中遇到的带input弹窗的错位问题
- Ballanspace v0.1.0 发布,基于 Unity 3D 的错位空间的平衡球游戏
- iframe内联框架之巧妙跨域
- 提升go编译器内联程度
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Android 源码设计模式解析与实战
何红辉、关爱民 / 人民邮电出版社 / 2015-11 / 79.00元
本书专门介绍Android源代码的设计模式,共26章,主要讲解面向对象的六大原则、主流的设计模式以及MVC和MVP模式。主要内容为:优化代码的首步、开闭原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特原则、单例模式、Builder模式、原型模式、工厂方法模式、抽象工厂模式、策略模式、状态模式、责任链模式、解释器模式、命令模式、观察者模式、备忘录模式、迭代器模式、模板方法模式、访问者模式、中介......一起来看看 《Android 源码设计模式解析与实战》 这本书的介绍吧!