【前端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年了,而现在自己好像没有什么成就,想想好惭愧,努力吧,少年!!!


目录
相关文章
|
20小时前
|
Web App开发 前端开发 iOS开发
CSS3 转换,深入理解Flutter动画原理,前端基础图形
CSS3 转换,深入理解Flutter动画原理,前端基础图形
|
2天前
|
前端开发
|
2天前
|
前端开发
【Web前端】CSS基本语法规范和引入方式&&常见选择器用法&&常见元素属性
【Web前端】CSS基本语法规范和引入方式&&常见选择器用法&&常见元素属性
|
2天前
|
缓存 移动开发 前端开发
【专栏:HTML与CSS前端技术趋势篇】HTML与CSS在PWA(Progressive Web Apps)中的应用
【4月更文挑战第30天】PWA(Progressive Web Apps)结合现代Web技术,提供接近原生应用的体验。HTML在PWA中构建页面结构和内容,响应式设计、语义化标签、Manifest文件和离线页面的创建都离不开HTML。CSS则用于定制主题样式、实现动画效果、响应式布局和管理字体图标。两者协同工作,保证PWA在不同设备和网络环境下的快速、可靠和一致性体验。随着前端技术进步,HTML与CSS在PWA中的应用将更广泛。
|
2天前
|
前端开发 JavaScript 开发者
【专栏:HTML与CSS前端技术趋势篇】前端框架(React/Vue/Angular)与HTML/CSS的结合使用
【4月更文挑战第30天】前端框架React、Vue和Angular助力UI开发,通过组件化、状态管理和虚拟DOM提升效率。这些框架与HTML/CSS结合,使用模板语法、样式管理及组件化思想。未来趋势包括框架简化、Web组件标准采用和CSS在框架中角色的演变。开发者需紧跟技术发展,掌握新工具,提升开发效能。
|
2天前
|
前端开发 JavaScript UED
【专栏:HTML 与 CSS 前端技术趋势篇】Web 性能优化:CSS 与 HTML 的未来趋势
【4月更文挑战第30天】本文探讨了CSS和HTML在Web性能优化中的关键作用,包括样式表压缩、选择器优化、DOM操作减少等策略。随着未来趋势发展,CSS模块系统、自定义属性和响应式设计将得到强化,HTML新特性也将支持复杂组件构建。同时,应对浏览器兼容性、代码复杂度和性能功能平衡的挑战是优化过程中的重要任务。通过案例分析和持续创新,我们可以提升Web应用性能,创造更好的用户体验。
|
2天前
|
移动开发 前端开发 UED
【专栏:HTML与CSS前端技术趋势篇】渐进式增强与优雅降级在前端开发中的实践
【4月更文挑战第30天】前端开发中的渐进式增强和优雅降级是确保跨浏览器、跨设备良好用户体验的关键策略。渐进式增强是从基础功能开始,逐步增加高级特性,保证所有用户能访问基本内容;而优雅降级则是从完整版本出发,向下兼容,确保低版本浏览器仍能使用基本功能。实践中,遵循HTML5/CSS3规范,使用流式布局和响应式设计,检测浏览器特性,并提供备选方案,都是实现这两种策略的有效方法。选择合适策略优化网站,提升用户体验。
|
2天前
|
前端开发 开发者 UED
【专栏:HTML与CSS前端技术趋势篇】网页设计中的CSS Grid与Flexbox之争
【4月更文挑战第30天】本文对比了CSS Grid和Flexbox两种布局工具。Flexbox擅长一维布局,简单易用,适合导航栏和列表;CSS Grid则适用于二维布局,能创建复杂结构,适用于整个页面布局。两者各有优势,在响应式设计中都占有一席之地。随着Web标准发展,它们的结合使用将成为趋势,开发者需掌握两者以应对多样化需求。
|
2天前
|
前端开发 JavaScript 搜索推荐
【专栏:HTML 与 CSS 前端技术趋势篇】HTML 与 CSS 在 Web 组件化中的应用
【4月更文挑战第30天】本文探讨了HTML和CSS在Web组件化中的应用及其在前端趋势中的重要性。组件化提高了代码复用、维护性和扩展性。HTML提供组件结构,语义化标签增进可读性,支持用户交互;CSS实现样式封装、布局控制和主题定制。案例展示了导航栏、卡片和模态框组件的创建。响应式设计、动态样式、CSS预处理器和Web组件标准等趋势影响HTML/CSS在组件化中的应用。面对兼容性、代码复杂度和性能优化挑战,需采取相应策略。未来,持续发掘HTML和CSS潜力,推动组件化开发创新,提升Web应用体验。
|
2天前
|
XML 前端开发 JavaScript
前端CSS样式零基础教学总结,UI、前端开发都适用
前端CSS样式零基础教学总结,UI、前端开发都适用