【前端Talkking】CSS系列——CSS深入理解之line-height

简介: 【前端Talkking】CSS系列——CSS深入理解之line-height

原文链接: segmentfault.com


1.写在前面

两个多周的时间没有写文章了,手好痒好痒,趁着公司在装修,从上周末到本周都在家办公,同时公司的项目并不紧急,于是抽着时间梳理了一下CSS中关于行高line-height的理解,今天发布出来,大家准备好了吗?


2.基本概念

2.1行高的定义与图解

行高,顾名思义指的就是一行文字的高度。按照定义来解释,就是两行文字之间基线之间的距离。那么问题来了,什么是基线呢?大家回想下我们刚开始学习汉语拼音的时候,使用四线格本子的四条线,其中倒数第二条线就是基线,如果你说,抱歉,我已经全部还给老师了,没有任何印象。呵呵,别急呢,我已经给大家准备好了,请看下面的这副图,其中,a、c、e、x、z等字母的底边线(倒数第二根线)就是我们说的基线。

了解完基线的定义后,我们接着来聊行高line-height。上面我们说过,行高就是两条基线的之间的距离,如下图所示。

大家是不是已经😓了,大家耐着性子仔细看下,其实挺好理解的:

  • 两条红线之间的距离就是行高(line-height)
  • 上一行的底线和下一行的顶线之间的距离就是行距,业界的共识是:行距=行高-em-box(暂时理解为font-size的大小),因此,用CSS语言来解释行距就是: 行距=line-height-font-size。
  • 同一行顶线和底线之间的距离就是font-size
  • 行距的一半就是半行距

结合上面图和文字描述,其实可以很容易搞清楚行高、行距、半行距、font-size的意思。大家一定要弄清楚这些定义,因为,下文中的内容和这些定义有关。

2.2 内容区、行内框、行框、包含框

所谓一图胜千言:

内容区:内容区域可以近似理解为FireFox/IE浏览器下文本选中带背景的区域,在上图中,深灰色背景区域就是内容区域。

行内框:每一个行内元素都会生成一个行内框,高度等于font-size,当我们设置line-height的时候,行内框的高度保持不变,改变的是行距的高度。

行框:指本行的一个虚拟的矩形框,由本行中的行内框组成。当有多行内容的时候,每一行都有自己的的一个行框。

包含框: 包裹着上述三种box的box,晕了,直接看图吧,上面黄颜色的框就是包含框。


3.深入理解line-height

3.1 line-height的各类属性值

line-height的默认值是normal,同时还支持数值、百分比值、长度值、继承。请看下面的表格:

描述
normal 默认。设置合理的行间距。
number 设置数字,此数字会与当前的字体尺寸相乘来设置行间距,即number为当前font-size的倍数。
length 设置固定的行间距。
% 基于当前字体尺寸的百分比行间距。
inherit 规定应该从父元素继承 line-height 属性的值。
  • normal

大家在使用line-height的时候,设置为该值很少,为什么呢?因为normal是一个与font-family有着密切联系的变量值。例如:

div{
    line-height: normal;
    font-family: 'microsoft yahei';
}

div{
    line-height: normal;
    font-family: 'simsun';
}


这两段代码在不同浏览器中测试数据如下:

字体 Chrome Firefox IE
微软雅黑 1.32 1.321 1.32
宋体 1.141 1.142 1.141

从上面的表格中可以看到,指定字体后,在不同浏览器中line-height的解析值基本是一样的。然而,不同的浏览器使用的默认字体不一样,并且不同的操作系统使用的默认字体也是不一样的。因此,我们在实际开发的时候,都需要对行高line-height进行重置操作。

  • inherit字面意思是继承,即继承父元素line-height的值,父元素是多少,当前节点的line-height就是多少,如果当前节点的子节点不设置任何的line-height,子节点的line-height也是这个值。
  • length也就是带单位的值,比如line-height: 21pxline-height: 1.5em等。如果当前的font-size为14px,则line-height计算后的值为1.5*14px=21px
  • number例如,line-height: 1.5,最终的计算值是和当前的font-size相乘后的值,比如font-size为14px,则line-height计算值是1.5*14px=21px
  • %例如,当前font-size为16px,line-height为120%,则计算后的行高为16*120%=19.2px

不知道大家发现没有,line-height:1.5line-height: 1.5em以及line-height: 150%这三种用法计算的结果 是一样的,最终计算的行高都是根据font-size来计算的。是不是它们可以相互替代呢?其实不然,实际上,line-height:1.5和另外两个的继承细节有些区别,我们直接看例子吧。

body{
    font-size: 14px;
    line-height: 1.5;
}
body{
    font-size: 16px;
    line-height: 150%;
}
body{
    font-size: 14px;
    line-height: 1.5em;
}

对于<body>元素而言,上面三种方式计算后的的行高都是21px,但是,如果body下还有子元素,例如:

<body>
    <h3>这是标题</h3>
    <p>这是内容</p>
</body>
h3, p{
    margin: 0;
}
h3{
    font-size: 32px;
}
p{
    font-size:  20px;
}

最终结果是line-height: 150%line-height: 1.5em的最终表现是两行文字重叠到了一起,如下图:

而设置了line-height:1.5的最终表现是两行文字没有重叠,排版良好,效果如下图:

设置line-height: 150%line-height: 1.5em后,子元素继承的是计算后的值,即21px,而不是继承150%和1.5em,所以<h3><p>的行高都是21px,而<h3>的font-size是32px,则根据上面的公式计算出来的半行距是-5.5px,因此,两行文字发生了重叠。

不同属性下的line-height最终的计算方式比较如下。

设置方式 line-height 计算后的line-height 子元素继承的line-height
inherit 父元素的line-height值 不用计算 父元素的line-height值
length 20px 不用计算 20px
% 150% 自身font-size (14px) * 150% = 21px 继承父元素计算后的line-height值 21px,而不是150%
normal 假如为1.2 自身font-size (16px) * 1.2 = 19.2px 继承1.2,line-height = 自身font-size(32px) * 1.2 = 38.4px
纯数字 1.5 自身font-size (14px) * 1.5 = 21px 继承1.5,line-height = 自身font-size(32px) * 1.5 = 48px

所以,在实际开发中, 我们一般设置行高的值为 `纯数字是最推荐的方式,因为其会随着对应的 font-size 而缩放,排版效果良好。

3.2 line-height的"大值特性"

现在,请大家仔细阅读下面的代码:

<div class="box">
    <span>这是内容...</span>
</div>
.box{
    line-height: 50px;
}
.box span{
    line-height: 10px;
}

.box{
    line-height: 10px;
}
.box span{
    line-height: 50px;
}

抛出问题:请问div的高度是多少?直接上正确答案:都是50px。请看图

感觉说不通啊,那么请看解释吧。

首先,我们要始终记着,内联元素前面有一个看不见的"幽灵空白节点",因此,上面的html代码可以等价为:

<div class="box">
    幽灵空白节点<span>这是内容...</span>
</div>

所以,当.box元素设置line-height:50px的时候,"幽灵空白节点"高度为96px,而当.box元素设置line-height: 20px的时候,span元素的高度变成了96px,而又因为行框盒子是由高度最高的那个内联盒子决定的,所以.box元素的高度永远是最大的那个line-height的原因,根据张鑫旭老师的总结,这可以称为line-height的大值特性,不知道这样解释大家清楚了没有呢?

3.3 line-height与内联元素"垂直居中"

  • 行高让单行文字"垂直居中"

不知道你是否和我一样,在刚开始写CSS的时候,控制单行文字垂直居中的时候,设置line-heightheight的值一样就可以实现文字垂直居中的效果,即:

.title{
    height: 50px;
    line-height: 50px
}

其实,这里只需要保留line-height这个属性就可以了,完全没有任何必要设置height的大小。

<div style="height: 50px; background-color: #cd0000; color: #fff">
    <span style="line-height: 50px">元素元素元素</span>
</div>

因此,流传比较广的"设置line-heightheight的值一样就可以实现文字垂直居中效果", 应该修改为:把line-height设置为您需要的box的大小可以实现单行文字的垂直居中

  • 行高让多行文字“垂直居中”

多行文字垂直居中效果需要借助line-height的好朋友的帮助才能实现,代码如下:

<div class="box">
    <div class="content">基于行高是实现的多行文本垂直居中...我发现文字很短,于是随便写了一点文字凑个数..</div>
</div>
.box{
    line-height: 120px;
    background-color: #cd0000;
    color: #fff;
}
.content{
    display: inline-block;
    line-height: 20px;
    margin: 0 20px;
    vertical-align: middle;
}

效果图如下所示:

实现的原理如下:

  1. 多行文字使用一个标签包裹,同时设置display: inline-block,保持了内联元素的特性,使元素具有单行效果,该设置使元素形成了一个非常关键的"行框盒子",而每一个行框盒子都会附带一个"幽灵空白节点"(宽度为0,但是表现和普通字符相同)。而我们设置了外层的line-height: 120px,因此,.content内容"幽灵空白节点"的line-height也将是120px;
  2. 内联元素默认是基线对齐的,通过设置vertical-align:middle可以实现我们想要的"垂直居中"效果。

3.4 真的是"垂直居中"吗

不知道大家有没有留意上文中的单行文本和多行文本的垂直居中都加了引号,难道还不是真正的垂直居中?没错,line-height实现的垂直居中效果只是近似的垂直居中。为什么是"近似"?我们拿一个例子说明问题:

<p>微软雅黑</p>
p{
    font-size: 80px;
    line-height: 120px;
    background-color: #cd0000;
    color: #fff;
    font-family: "Microsoft YaHei";
}

在浏览器中(windows系统)的效果如下:

大家看到没有,这些文字的位置明显偏下。因为,有些字体的位置偏下,比如"微软雅黑",在平时我们使用的过程中,字体大小基本在16~18px之间,虽然下沉,但是也就是1px的偏差,我们的肉眼根本察觉不到。因此,使用line-height实现的"垂直居中"并不是绝对的垂直居中

同理,使用line-heightvertical-align实现的多行文本垂直居中也不是绝对的垂直居中,在上文中多行文本垂直居中的例子中,我们可以明显的看到字体位置偏下。

其实,不居中并不是line-height导致的,而是他的好基友vertical-align造成的,我们会在vertical-align文章中详细阐述,敬请期待。

4. 最后

关于line-height的介绍就到这里了,平时我们应该多思考,多总结,才会有新的体会。以后我的最新文章都会第一时间更新在公众号<前端Talkking>里面,欢迎大家关注。

以上就是本文的全部内容,感谢阅读,如果有表述不正确的地方,欢迎留言指正!😄

ps:这两天是一年一度的高考,想想自己的高考差不多过去了10年了,而现在自己好像没有什么成就,想想好惭愧,努力吧,少年!!!


目录
相关文章
|
3月前
|
前端开发 JavaScript 算法
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
transition过渡属性 早期在Web中要实现动画效果,都是依赖于JavaScript或Flash来完成。 但在CSS3中新增加了一个新的模块transition,它可以通过一些简单的CSS事件来触发元素的外观变化, 让效果显得更加细腻。简单点说,就是通过鼠标经过、获得焦点,被点击或对元素任何改变中触发, 并平滑地以动画效果改变CSS的属性值。 在CSS中创建简单的过渡效果可以从以下几个步骤来实现: 在默认样式中声明元素的初始状态样式; 声明过渡元素最终状态样式,比如悬浮状态; 在默认样式中通过添加
258 0
|
3月前
|
前端开发 JavaScript 算法
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
transform变形 css3在原来的基础上新增了变形和动画相关属性,通过这些属性可以实现以前需要大段JavaScript才能实现的 功能。 CSS3的变形功能可以对HTML组件执行位移、旋转、缩放、倾斜4种几何变换,这样的变换可以控制HTML组件 呈现出丰富的外观。 借助于位移、旋转、缩放、倾斜这4种几何变换,CSS3提供了transition动画。 transition动画比较简单,只要指定HTML组件的哪些CSS属性需要使用动画效果来执行变化,并指定动画时间,就可保证动画播放。 比transitio
208 1
|
3月前
|
前端开发 算法 Java
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
Flex 布局 布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。 2009年,W3C 提出了一种新的方案----Flex 布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。 一、Flex 布局是什么? Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。
312 1
|
3月前
|
前端开发 算法 Java
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
盒模型 盒模型: 所谓盒模型,就是浏览器为页面中的每个HTML元素生成的矩形盒子。 这些盒子们都要按照可见板式模型在页面上排布。 可见的板式模型主要由三个属性控制:position 属性、display 属性和 float属性。 position属性控制页面上元素间的位置关系。 display属性控制元素是堆叠、并排或者不在页面上显示。 float属性提供控制的方法,以便于把元素组成成多栏布局。 盒模型讲解: 在默认的情况下,每个盒子的边框是不可见的,背景也是透明的。 所以我们 不能直接的看到页面中的盒
199 1
|
3月前
|
前端开发 算法 Java
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
伪类:伪类这个叫法源自于它们跟类相似,但实际上并没有类会附加到标记中的标签上。 伪类分为两种(以及新增的伪类选择器): UI伪类:会在HTML元素处于某种状态时(例如:鼠标指针位于连接上),为该元素应用CSS样式。 :hover 结构化伪类:会在标记中存在某种结构上的关系时 例如: 某元素是一组元素中的第一个或最后一个,为该元素应用CSS样式。 :not和:target(CSS3新增的两个特殊的伪类选择器)
213 1
|
3月前
|
前端开发 算法 Java
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
上下文选择器(迭代选择器):基于祖先或同胞元素选择一个元素 ID和类选择器:基于id#和class的属性值进行选择元素。 属性选择器:基于属性的有无和特征进行选择。 ①上下文选择器: 上下文选择器的语法格式:标签1 标签2{属性:值;} //注意:组合选择器和上下文选择器的区别,组合选择器以逗号隔开, 上下文选择器以空格隔开 ②特殊的上下文选择器 子选择器> : 语法格式:标签1>标签2 解释说明:标签1和标签2
285 1
|
3月前
|
前端开发 算法 Java
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
Animation属性 css3为Animation动画提供的几个属性如下: 属性名 属性值 animation-name 指定动画名称,该属性指定一个已有的关键帧定义。 animation-duration 指定动画持续时间。 animation-timing-funtion 指定动画变化速度。 animation-delay 指定动画延迟多长时间才开始执行。 animation-iteration-count 指定动画的循环执行次数。 animation:这是一个复合属性。
300 2
|
3月前
|
前端开发 算法 Java
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
position定位(核心) 我们讲盒模型的时候,提到了3个属性可以用来控制页面排版。 三大属性:position属性,display属性,float属性。 position 属性控制页面上元素间的位置关系。 display 属性控制页面元素是否显示或者是堆叠还是并排显示。 float 属性提供控制方法。 通过float这种控制方法,可以实现多栏布局,导航菜单等等。 position属性是干嘛用的?怎么用?有哪些属性值? position属性控制页面上元素间的位置关系,也就是排版。 怎么用?要知道怎么用
452 1
|
3月前
|
前端开发 算法 Java
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
继承 我们的CSS中很多的属性也是可以继承的,其中相当一部分是跟文字的相关的,比如说颜色、字体、字号。 当然还有一部分是不能继承的。 例如边框、内外边距。 层叠 层叠是CSS的核心机制。 层叠的工作机制: 当元素的同一个样式属性有多种样式值的时候,CSS就是靠层叠机制来决定最终应用哪种样式。 层叠规则: 层叠规则一:找到应用给每个元素和属性的声明。 说明:浏览器在加载每个页面时,都会据此查找到每条CSS规则, 并标识出所有受到影响的HTML元素。
145 0
|
9月前
|
前端开发

热门文章

最新文章