作者:极客小俊
一个把逻辑思维转变为代码的技术博主
我不用拼过聪明人,我只需要拼过那些懒人 我就一定会超越大部分人!
原创技术文章
字母x与css中ex单位之间的概念
上面也说过了, vertical-align: middle 并不是绝对的垂直居中于文字对齐! middle也只是一种近似接近于居中的效果!
就是因为不同的字体在行元素中的位置是不一样的!中线位置也不一样,所以说对齐方式也不一样。
同时如果font-size字体大小有变化的情况下, x字母的高度也会随之变化, 然后内联元素依旧会以小写字母x的中线为基准对齐
举个例子:
如果用一个小图标来对齐一行文字,那么在文字大小和字体样式有变化之后,给小图标设置vertical-align: middle 后,它依旧会按照x中线对齐, 但这个小图标的从大小上感觉没有对齐,也从外部元素的高度上来看,所以小图标感觉也没有垂直居中对齐的样子!
如下图所示:
所以要让一个小图标来对齐一行文字,还有一个更加简便的做法 那么就是使用ex单位来解决!
ex 在css中的定义是一个尺寸单位, 官方的解释是: 一个 ex 是一个字体的 x-height。(其实就是你设定的字体中产生的x的大小)
我的解释 : ex 就是css中的一个相对单位, 相对的是字体大小和字体样式而改变的一个单位! 指的就是小写字母x的高度 其实就是x-height
也就是说把内联元素的高度尺寸单位设置为ex 那么就不会受到 字体样式和字号的影响! 从该内联元素相对字体样式和字号进行变化!
1ex 就是一个x的高度这句话如何理解: 就是在不同字体和字号情况下x的高度!
那么也就是说把小图标的高度设置为1ex 那么不管你把字体大小 和 字体样式如何修改, 这个小图标都会随着他们而变化!
案例:
北京市 iphone x
北京市 iphone x
北京市 iphone x
效果如下:
不管如何修改字体大小和字号 小图标都会更好的去垂直居中, vertical-align: middle;也没必要使用了! 借助ex这个相对单位我们直接利用默认的baseline基线对齐就可以实现小图标内联元素和文字进行居中的效果了! 注意:经过审查元素看到每一行小图标和文字中的字母x高度始终是一样的!
小结: ex相对单位不会受字体和字号的影响! 虽然ex单位跟line-height没有直接关系,但也有间接关系!
回顾什么是内联元素!
内联元素从定义上看: 该元素默认的display属性值为inline、inline-block、inline-table的元素就是内联元素。
内联元素从表现上看: 典型的特征就是内联元素可以和文字在一行进行显示, 这里注意: 文字本身也是一个内联元素(是匿名内联元素 马上会接下来会说到), 所以我们常见的内联元素从表面上看有文字、 图片、按钮、输入框、下拉框、等原生表单控件都是内联元素!
内联盒模型 (重点核心)
在我们学习line-height这个属性的时候, 我们还必须要了解CSS中一个重要的概念 就是内联盒模型 那么我们先来看一段代码案例, 这一段文字代码看似简单 但其中包含很多术语和概念,通俗的说这一段代码中包含很多种类的盒子!
如下:
这是一行普通的文字, 这里有一个 我是斜体 标签
从以上代码中 我们来分析它里面到底有哪些盒子!
(1) 内容区域 content area
内容区域是一种我们肉眼看不见的盒子,它围绕着文字 我们平常是看不见这个盒子的!
通俗理解: 其实可以通过选中文本然后查看背景颜色区域作为内容区域来理解!
小提示:但是要注意的是 如果是图片,其内容不是文字,不存在内容区域之说 因此对于图片这类元素可以把内容区域看作是元素自身!
也就是说如果是图片的话,那么内容区域的大小是随着图片的大小来决定的!
这样理解内容区域可以帮助我们理解各种相关内联元素的行为都是可以的!
如下图:
内容区域小结
- 我们先记住一点: 文字选中的背景颜色区域就把它看做为: 内容区域!
- 内容区域 (content area) 的高度会受到font-family(字体)和font-size(字号)的影响!
- 并且有时候哪怕是当前元素的font-size(字号大小)在不变的情况下, 但也有可能因为 font-family(字体)设置的不同最后导致内容区域 (content area)不一样!
- 内容区域顶线和底线包裹的区域就是内容区域,如果font-size 或 font-family有变化 那么顶线和底线位置也会变化。
- 我们在设置font-size 或者 font-family的时候,实际上都会改变内容区域的大小! 所以内容区域高度与字号以及字体有关!
- 这里还有一个重点就是内容区域 是不能使用width和height进行设置宽高的!
总的来说内容区域:就是底线和顶线包裹的区域(行内元素display:inline可以通过background-color属性显示出来),实际中不一定看得到,但确实存在。内容区的大小依据font-size的值和字数进行变化。
如下图:
[图片上传失败...(image-f51e18-1614331885063)]
(2) 内联盒子(行内框) inline box
说到内联盒子 那么大家一定就不会陌生了 就是我们平常使用的内联元素(行内元素)!
内联盒子也称之为: 行内框 这要特别注意 这是针对行元素而言的, 每个行内元素会生成一个行内框,行内框是一个浏览器渲染模型中的一个概念 无法肉眼观测!
它让内容成为一行排列 所以内联盒子就是指的内联元素, 简单的说就是文字用的什么内联元素来包含!
例如: span、em、a、这些都属于 内联盒子(行内框)!
注意:行内框 = 内容区域
内联盒子的分类
但是内联盒子则又会细分为 内联盒子 和 匿名内联盒子
所以 常见的内联盒子 如文字外部包含的是 span、a、em、strong、等这些标签 那么则属于 内联盒子
如果 是光秃秃的文字 则属于 匿名内联盒子 所以要注意 光秃秃的文字其实也是一种内联盒子!只是没有标签名字而已!
如下图:
特别案例
我们在设定line-height行高时,行内框(也就是内联盒子)的高度是不会有任何变化的,不知道大家有没有注意到这个情况!
如下案例:
重庆市
北京市
深圳市
如图: 我给strong设定了line-height为30px 但strong的高度依旧是19.8 其他两个内联盒子也是一样的高度 并没有影响,
影响的是strong上下周围的区域 也就是分别增加/减少到内容区域的上下两边灰色的部分! 并且上下的灰色部分的高度是一致的!
这也就是我们待会要讲解到的行框与行间距(行距)、(半行距)的概念
[图片上传失败...(image-4a25f6-1614331885063)]
(3) 行框盒子 line box
每一行就是一个行框盒子,那什么又叫做每一行呢 ?由多个内联盒子组合而成的一行 就会形成一个行框盒子
所以反推每一个行框盒子又是由一个个内联盒子组成而来的!
注意: 是每一行都会形成,如果文字有五行,就会形成5个行框。
如下图:
绿色框部分就是由一个一个的内联盒子组成的 最终这一个整体就叫做一个 行框 或者叫 行框盒子
==小提示:== 如果有换行符 把字符和元素换到下一行那么 下一行就是一个新的行框! 就相当于有多行内容时,每行都会有自己的行框
注意: 并且 行框高度等于本行框内部,所有行内框(内联盒子)中,最大的那个行内框(内联盒子)的值! 重点: 是以带有行高值最大的行内框(内联元素)为基准来最终计算行框的高度,其他行内框(内联元素)采用自己的对齐方式向基准对齐!
简单的说 就是 行间距 + 字体大小 = Line-height的高度 就是这个高度撑开了行框! (行间距包含在行框内部的!) 为了方便理解请看下图:
[图片上传失败...(image-379851-1614331885063)]
从上图可以看出来 所有的内联元素都是以基线对齐的上面已经说过了,但重要的是 第二个内联元素具有行高, 产生了行间距 所以就以第二个内联元素为基准来计算行框最终的高度!
备注: 设置line-height属性会影响行框的布局? 这句话的意义何在?
答案就是: line-height 与 font-size 的计算值之差(行距)分为两半,分别加到一个内联元素的顶部和底部 而且计算出来的差值分别加到内容区域的顶部和底部的就是行距 所以实质上撑开 行框 的是line-height行高其中的行距!
(4) 包含盒子 containing box
这段代码中的p标签就是一个包含盒子! 包含盒子的内部就是由一行一行的行框盒子组成!
一个行框盒子 说明只有一行, 多个行框盒子说明是多行! 当然也有人称呼它为 包含块(containing block)
如下图:
粉红色部分的就是包含块部分! 包含块最终把这一行整合为一个整体!
(5) 幽灵空白节点
这个概念听起来就很玄乎! 很奇特 但其实也是在内联盒模型中一个很重要的概念!
概念理解: 在浏览器对内联元素的解析和渲染中 每一个行框 前面都有一个 ==空白节点== 但很奇特的是这个空白节点永远是看不见透明的 并且也不占据任何宽度 也就是说 宽度为0, 是的 肉眼看不见 也无法通过脚本去获取到 就好比幽灵一般! 但又的的确确是存在的! 就跟文本节点一样 所以 大家都称为它是 幽灵空白节点
注意: 有一个前提条件 它主要是在HTML5的文档声明中才有这个情况,其他老一点的文档声明则不存在 幽灵空白节点!
我们来看一个案例 就会马上了解 如下:
注意: 这里我们并没有设置任何高度! 而结果却是如下图所示:
此时你看见结果后一定会很惊讶 为什么div的高度不是0呢? 我们并没有给div设置任何高度呀 对吧 并且内部span的高度我们也没有设置呀 高度也应该是0 那么div的高度20px是如何来的呢? 这就是我们刚刚说的 幽灵空白节点 的缘故
其实原因就是 : 浏览器对内联元素的解析和渲染中 每一个行框 前面都有一个 ==空白节点== 那么这里就是在span元素的前面还有一个宽度为0的空白字符!
并且其实它也是一个盒子 不过是一个抽象的盒子 官方定义名称为: strut (支柱) 重点来了, 并且这个空白字符strut(支柱) 是一个存在于每个行框盒子 内部的最前面 它的宽度只有0px,看不到的, 同时这个 strut (支柱)的行高和字体大小都与该元素相同! 简单的先知道这个概念就可以了 至于高度从何而来我们后面再细说!
图解如下:
CSS官方对strut (支柱) 的介绍: [了解]
Each line box starts with a zero-width inline box with the element's font an d line-height properties. We call that imaginary box a "strut"!
我们来看一个跟幽灵空白节点有关的案例:
效果:
此时 div的高会成为256px, 有人会认为这是把图片的高度改变了,其实不是 而是line-height把 幽灵空白节点上下的行距增大从而改变了 因为图片是内联元素 会形成一个 行框盒子 在HTML5文档模式下, 每一个行框盒子前面都有一个宽度为0的 幽灵空白节点 前面也提到过了 这个幽灵空白节点的特性和普通字符一模一样也就是它是一个隐藏的内联元素 所以其实是这个幽灵空白节点被设置了上下行距为122像素的缘故 撑开了行框 ,而行框最后撑开了外面的div元素!
了解幽灵空白节点为后续更好的认识内联元素打好坚实的基础!
line-height与内联元素高度之间的关系
先提出一个问题: 不管是内联元素 还是 块元素 在他们没有设置高度并且里面也有文字内容的情况下 元素的高度从何而来?
很多人认为是由文字撑开! 实际上却不是, 而是line-height的高度决定的!
案例1:
通过测试我们可以看出 .test1 元素虽然设置了font-size为36px 但line-height设置为0后 .test1元素显示成了一根线! 并没有像有些人所说的文字会撑开! 而.test2虽然font-size设为了0 文字看不见了,但line-height设为了36px 它却把 .test2元素撑开了! 原理跟上面所讲到的 幽灵空白节点 一致! (个人理解)
案例2
北京市
北京市
北京市
北京市
北京市
北京市
北京市
北京市
效果如下:
[图片上传失败...(image-8ea2eb-1614331885063)]
从上图看 通过给内联元素span、em设置line-height , 他们的可视高度没有变,但他们的彼此撑开了外部包含的div 那么是什么撑开的呢?
答案是: line-height撑开了行框盒子 然后这个行框盒子从我们肉眼上看是看不见的, 但它又可以撑开外部的div 所以就看到现在两行文字彼此之间有距离了!
所以从图中看, 内联元素设置line-height但内联元素本身高度是没有变化,但每一行的行框的高度改变了, 从人的视觉上是看不出来的! 而撑开的这个高其实就叫 行距
![](http://img.e-com-net.com/image/info10/7e322f7139064ee4834ad91fdb328fee.gif)
![](http://img.e-com-net.com/image/info10/c638b4373723470daa3621a0cc6b9764.gif)
如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏”
一键三连哦!
如果以上内容有任何错误或者不准确的地方,欢迎在下面 留个言指出、或者你有更好的想法,欢迎一起交流学习