CSS深入理解vertical-align和line-height基友关系的复杂现象

本文主要是介绍CSS深入理解vertical-align和line-height基友关系的复杂现象,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

为了让任意个数的列表最后一行也是对齐排列,在列表最后会辅助列表等宽的空标签元素来占位,类似下面红色高亮HTML代码:

.justify-fix { display: inline-block; width: 128px; }
<div style="text-align: justify;"><img src="img/mm1.jpg" width="128"><img src="img/mm1.jpg" width="128"><img src="img/mm1.jpg" width="128"><img src="img/mm1.jpg" width="128"><i class="justify-fix"></i><i class="justify-fix"></i><i class="justify-fix"></i>
</div>

图示意:

这里写图片描述

同样的,在白色背景下,似乎看上去效果还不赖,但是,如果给div容器加个背景色~~

这里写图片描述

会惊讶的发现,下面多了很大一块间隙.

为了便于大家看其究竟,我把占位i元素outline高亮下,于是,效果如下:

这里写图片描述

结果会发现,上面巨大的空隙是由占位i元素上面和下面的间隙共同组成的。

下面问题来了:上面的间隙是如何产生的?下面的间隙是如何产生的?如果去除这些间隙呢?

很多时候,复杂问题是由简单问题组合而成的,实际上,这里的间隙现象的始作俑者和上面的简单现象一样,都是vertical-align和line-height搞基带来的不好的影响。

按照之前问题解决方法,我们可以直接来个line-height:0解决垂直间隙问题:

div { line-height: 0; }

结果图片和图片之间的间隙是没有了,但是,图片和最后的占位元素之间依然有个几像素的间距,,啊啊啊啊,这究竟是什么鬼?

这里写图片描述

简单现象的背后往往有大的学问,接下来是本文的高潮了,究其原因,要说到inline-block元素和基线baseline之间的一些纠缠的关系。

⑤ inline-block和baseline

CSS2的可视化格式模型文档中有一么一段话:

The baseline of an ‘inline-block’ is the baseline of its last line box in the normal flow, unless it has either no in-flow line boxes or if its ‘overflow’ property has a computed value other than ‘visible’, in which case the baseline is the bottom margin edge.

直译一下:
‘inline-block’的基线是正常流中最后一个line box的基线, 除非,这个line box里面既没有line boxes或者本身’overflow’属性的计算值而不是’visible’, 这种情况下基线是margin底边缘。

这段文档中出现了很多专有名词line box, line boxes等,这些是内联盒子模型中的概念,是CSS进阶必备知识。
如果大家没有足够精力去学习之,可以先看下面这张图:

这里写图片描述

上图引用张大神的

由于上面的译文是直译的,理解起来还是有些拗口,我使用通俗的话描述就是:一个inline-block元素,如果里面没有inline内联元素,或者overflow不是visible,则该元素的基线就是其margin底边缘,否则,其基线就是元素里面最后一行内联元素的基线。

纳尼,还是没反应过来?

那我们看下面这个例子,应该就知道什么意思了。

两个同尺寸的inline-block水平元素,唯一区别就是一个空的,一个里面有字符,代码如下:

.dib-baseline {display: inline-block; width: 150px; height: 150px;border: 1px solid #cad5eb; background-color: #f0f3f9;
}
<span class="dib-baseline"></span>
<span class="dib-baseline">x-baseline</span>

结果,科科:
这里写图片描述

会发现,明明尺寸、display水平都是一样的,结果呢,两个却不在一个水平线上对齐,为什么呢?哈哈,上面的规范已经说明了一切。第一个框框里面没有内联元素,因此,基线就是容器的margin下边缘,也就是下边框下面的位置;而第二个框框里面有字符,纯正的内联元素,因此,第二个框框就是这些字符的基线,也就是字母x的下边缘了。于是,我们就看到了框框1下边缘和框框2里面字符x底边对齐的好戏。框框2有个小彩蛋,点击可以toggle其innerHTML,会发现,如果框框2里面没文字,就和框框1举案齐眉了。

下面我们要做一件很有必要的事情,用来帮助我们理解上面复杂例子在line-height值为0后的表现,什么事情呢?哈,同境界模拟,我们也设置框框2的line-height值为0,于是,就会是下面这样的表现:

这里写图片描述

知道框框2为何又下沉了一点吗?

因为字符实际占据的高度是由行高决定的,当行高变成0的时候,字符占据的高度也是0,此时,高度的起始位置就变成了字符content area的垂直中心位置,于是,文字就一半落在看看2的外面了。

由于文字字符上移了,自然基线位置(字母x的底边缘)也往上移动了,于是,两个框框的垂直落差就更大了。

OK,明白了上面的简单例子,也就能明白上面的复杂例子。紧接着,如果我们在最后一个占位的元素后面新增同样的x-baseline字符,则:

这里写图片描述

额~居然还有小伙伴皱眉头,那我再用文字解释下:
现在行高line-height是0, 则最后的x-baseline的垂直中线就和上面一列的图片对齐,而基线呢,就在中线下面差不多半个x的高度地方,而这个高度落差就是最后图片和容器的间隙高度值,因为前面的<i class="justify-fix">是个空元素,基线是自身的底部,哈哈,造业啊!

OK,一旦知道了现象的本质,我们就能轻松对症下药了!要么改造占位<i>元素的基线、要么改造“幽灵空白节点”的基线位置、要么使用其他vertical-align对齐方式~

首先,来个最有意思的方法,对吧,改造占位<i>元素的基线。这个很简单,对吧,只要在空的<i>元素里面随便放几个字符就可以了,例如,里面有个x:

这里写图片描述(这之前忘记加div的line-height:0;导致图片下方有空隙。)

改造“幽灵空白节点”的基线位置,哈哈,使用font-size,字体足够小时,基线和中线会重合在一起,什么时候字体足够小呢,就是0. 于是,CSS代码(line-height如果是相对值,line-height:0也可以省掉):

div { font-size: 0; }

这里写图片描述

使用其他vertical-align对齐方式,就是让两端对齐的列表元素vertical-align:top/bottom/…之类。

div { line-height: 0; }
.justify-fix { display: inline-block; width: 128px; vertical-align: top; }

这里写图片描述

恩恩,各种方法都完美解决了垂直间隙的问题,

基友关系暴露之后

这里写图片描述

至此,vertical-align和line-height的断背基友关系算是彻底暴露了,而且,从行为表现上来看,line-height是攻,vertical-align是个受。而很多内联元素的行为表现,就是这对基友搞七搞八一起搞出来的。

以前,关系处于地下的时候,我们可能不会明白,为何男厕所的卷纸用得比女厕所还快;但是,现在关系暴露了,很多以前我们想不明白的事情一下子就豁然开朗了。

因此,我们要以正确地心态去看待这对好基友,毕竟,他们可以CSS届非常重要的两个主力大将。

本文牵扯的知识点甚多,建议大家如果想在重构领域有所造诣,很多基本的却很深入的东西是很有必要弄透的。篇幅有限,有不少知识点都是一笔带过的,大家若有疑问,可以自己去检索与研究,例如,vertical-align各个值的规范解释,内联盒子模型,等等。也欢迎各种方式交流。

本文为原创文章,包含脚本行为和样式控制,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:http://www.zhangxinxu.com/wordpress/?p=4925

这篇关于CSS深入理解vertical-align和line-height基友关系的复杂现象的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/821186

相关文章

Java Stream流使用案例深入详解

《JavaStream流使用案例深入详解》:本文主要介绍JavaStream流使用案例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录前言1. Lambda1.1 语法1.2 没参数只有一条语句或者多条语句1.3 一个参数只有一条语句或者多

HTML5中的Microdata与历史记录管理详解

《HTML5中的Microdata与历史记录管理详解》Microdata作为HTML5新增的一个特性,它允许开发者在HTML文档中添加更多的语义信息,以便于搜索引擎和浏览器更好地理解页面内容,本文将探... 目录html5中的Mijscrodata与历史记录管理背景简介html5中的Microdata使用M

html5的响应式布局的方法示例详解

《html5的响应式布局的方法示例详解》:本文主要介绍了HTML5中使用媒体查询和Flexbox进行响应式布局的方法,简要介绍了CSSGrid布局的基础知识和如何实现自动换行的网格布局,详细内容请阅读本文,希望能对你有所帮助... 一 使用媒体查询响应式布局        使用的参数@media这是常用的

HTML5表格语法格式详解

《HTML5表格语法格式详解》在HTML语法中,表格主要通过table、tr和td3个标签构成,本文通过实例代码讲解HTML5表格语法格式,感兴趣的朋友一起看看吧... 目录一、表格1.表格语法格式2.表格属性 3.例子二、不规则表格1.跨行2.跨列3.例子一、表格在html语法中,表格主要通过< tab

Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案

《Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案》:本文主要介绍Vue3组件中getCurrentInstance()获取App实例,但是返回nu... 目录vue3组件中getCurrentInstajavascriptnce()获取App实例,但是返回n

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的

前端CSS Grid 布局示例详解

《前端CSSGrid布局示例详解》CSSGrid是一种二维布局系统,可以同时控制行和列,相比Flex(一维布局),更适合用在整体页面布局或复杂模块结构中,:本文主要介绍前端CSSGri... 目录css Grid 布局详解(通俗易懂版)一、概述二、基础概念三、创建 Grid 容器四、定义网格行和列五、设置行

深入理解Apache Kafka(分布式流处理平台)

《深入理解ApacheKafka(分布式流处理平台)》ApacheKafka作为现代分布式系统中的核心中间件,为构建高吞吐量、低延迟的数据管道提供了强大支持,本文将深入探讨Kafka的核心概念、架构... 目录引言一、Apache Kafka概述1.1 什么是Kafka?1.2 Kafka的核心概念二、Ka

前端下载文件时如何后端返回的文件流一些常见方法

《前端下载文件时如何后端返回的文件流一些常见方法》:本文主要介绍前端下载文件时如何后端返回的文件流一些常见方法,包括使用Blob和URL.createObjectURL创建下载链接,以及处理带有C... 目录1. 使用 Blob 和 URL.createObjectURL 创建下载链接例子:使用 Blob

Vuex Actions多参数传递的解决方案

《VuexActions多参数传递的解决方案》在Vuex中,actions的设计默认只支持单个参数传递,这有时会限制我们的使用场景,下面我将详细介绍几种处理多参数传递的解决方案,从基础到高级,... 目录一、对象封装法(推荐)二、参数解构法三、柯里化函数法四、Payload 工厂函数五、TypeScript