01|字母x CSS世界中隐匿的举足轻重的角色
因为涉及到排班或者说对齐的,其实都是离不开一个基本的概念:baseline(基线)
line-height行高的定义就是两基线的间距,vertical-align的默认值也是基线(字母x的下边缘)!
01|字母X与CSS中的x-height
其中x-height是CSS中的一个概念,表示小写字母x的高度,其术语的意思表示为 baseline和midline之间的距离!
其中在所谓的排版中还有另外一些概念,如下所示:
- ascender height 上行线高度
- cap height 大写字母高度
- median 中线
- descender 下行线高度
其中CSS中有些概念和这个所谓的x-height还是有关系的! 典型的代表就是 vertical-align:middle;
middle表示中间的意思,其实和上面介绍的median是没有关系的, middle表示的是 基线往上1/2 x-height的高度
我们的话可以立即为x交叉点的位置!
但是微软雅黑相较于别的字体来看是字符下沉比较厉害的字体,一年春vertical-align:middle; 不是相对容器中分线对齐的了!
其实这又说到了 因为CSS世界中的主题是文字,内容元素对齐是相对于文字对齐的,而并非外部的块级容器!
02|字母x与CSS中的ex
ex其实就是IE6都老早支持的ex单位,其实也是一个CSS中的一个相对单位,指的就是小写x的高度! 也就是所谓的 x-height!
其实所谓的em,px还是受字体等CSS属性影响较大! 由于字母x受字体影响比较大,不稳定,因此ex也不适合来限定元素的尺寸!
但是他的应用场景体现在 不受字体和字号影响的内联元素垂直居中对齐!
我们设置垂直居中的时候 就可以借助这个ex来进行垂直居中!
预览请见:https://demo.cssworld.cn/5/1-1.php
因为不管字体怎么变换 内联元素都是按照文字基线对齐的,
02|内联元素的基石line-height
div高度是由行高决定的并非文字,通过p114中的案例就可以很好地说明了!
并对于纯非替换元素的内联元素,可视高度完全有line-height决定!
那么如果说替换元素或者说是块级元素那么对应的line-height其中有扮演着什么角色呢?
其中就需要很好的理解所谓的 行距和半行距 的概念了!
当前文字的上方和下方的间距都是半间距! 半间距仅仅是行距高度的一半!
其实所谓的 行距=行高-字体盒子 || 行距=(line-height)-(font-size)
01|为什么line-height可以让内联元素"垂直居中"
我们一般流传着 高度和行高一致 可以让单行文字垂直居中!
其实这种说法不严谨,误区二,其实行高控制不仅仅适用于单行,其实多行也是可以的!
详情见p119
那么为什么说垂直居中说法不严谨呢? 其实详细通过测量会发现 还是会发现细微差别的! 其实和line-height无关,而是与vertical-align相关的!
02|line-height的好朋友vertical-align
为什么说line-height的好朋友是vertical-align呢? 因为凡事line-height起作用的地方vertical-align也一定的起了作用,但是大部分默默地起了作用 只是我们不知道而已!
其实可以通过一个小的案例体现出来:
<style>
.box{line-height:32px;}
.box > span{font-size:24px;}
</style>
<div class="box">
<span>文字</span>
</div>
通过这段代码,看看具体的行高为多少?
可能有些人看到了会认为是32px,其实没有设定height属性,所以高度就有line-height来确定,因此这里明摆着的高度就是为32px,其实事实却不是如此,其实实际上要比32px要大上几像素!(和对应的字体相关 )
实际的效果通过鼠标选中 发现对应的高度不为line-height的高度32px!
其实所谓的box的高度不等于line-height,之所以对应的行高不等于对应的32px就是因为line-height的"朋友"搞的鬼!
03|vertical-align家族基本认识
抛开对应的inherit这类全局属性不谈的话,可以将对应的vertical-align的属性值分为4类:
- 线类: baseline top middle bottom
- 文本类: text-top text-bottom
- 上标下标类: sub,super
- 数值百分比类: 20px 2em 20%
其实所谓的数值百分比 其实应该分为 数值类 和对应的 百分比类 因为他们之间有不同的共性
具有相同的渲染规则 根据计算值的不同 相对于基线往上或者是往下偏移!
并且默认的对齐方式 是按照基线对齐,因此如果如果说对应的vertical-align的值为正数的话 那么则向上偏移 如果为负数的话 则向下偏移 也就可以验证对应的baseline其实是对应着vertical-align的默认值为0!
对应的vertical-align:middle也不是百分之百的垂直居中的,其实还是有些差别的 并且对应的差别也是由于这个字体和字号所决定的!
并且在CSS世界中,凡是百分比的值均是需要一个相对计算的值的,比如说margin和padding的话 是相对于宽度计算的,line-height是相对于font-size计算的,而这里的vertical-align属性的百分比值则是相对于line-height的计算值计算的!
01|vertical align作用的前提
其实vertical align作用的前提就是:只能够应用于内联元素以及display值为table-cell的元素!
也就是说了 只能作用于 inline,inline-block,inline-table或者说table-cell的元素上面!
当然有些属性设置会改变元素的display的值的! 就比如说 浮动或者说绝对定位 会导致元素变成块级元素!
有人说table-cell会无视行高,其实并不是这样的,而是对应的vertical-align起作用的是table-cell元素自身!
02|vertical-align和line-height之间的关系
其实vertical-align和line-height之间的关系比较明确,就是"朋友关系",因为最明显的就是vertical-align计算的,但是表面所见的这点关系实际上只是冰山一角!
之前介绍到的设定了行高和对应的字号大小,之后的话呢,高度是否等于对应的行高,最后的结果却不是我们所设定的行高!
其主要原因是因为字号的印象,因为文字全部是按照基线对齐,因此当两个字号不同的蚊子在一起的时候,彼此会发生上下位移,如果位移距离足够大的话,就会超过行高的限制!
其实间隙产生的三大元凶便是:
- 幽灵空白节点
- line-height
- vertical-align
为了更好地理解,我们将在幽灵节点的位置放置字母x替代 幽灵空白节点!
如何更好地解决这个问题:
- 图片块状化
- 容器的line-height足够小
- 容器的font-size足够小
- 图片设置vertical-align属性值!
03|深入理解vertical-align线性类属性值
inline-block与baseline,vertical-align的属性的默认值baseline在文本之类的内联元素那里就是字符x的下边缘,对于替换元素则是替换元素的下边缘但是如果说是inlineblock元素的话规则则要复杂一些了:
一个inline-block元素如果说里面没有内联元素的话,或者overflow不是visible则该元素的基线就是其margin底边缘;否则其基线里面最后一行内联元素的基线!
这里的话,分享一下总结的一套基于20px图标对齐的处理技巧,该技巧有以下3个要点:
图标高度和当前行高都为20px 将图标原先拓展成统一规格! 可以节约大量CSS以及对每一个图标对其进行不同处理的开发版本
图标标签里面永远有字符 这个可以借助对应的:before和:after伪元素生成一个空格字符串轻松搞定!
图标CSS不使用overflow:hidden保证肌纤维里面字符的基线,但是要让里面潜在的字符不可见!
04|了解vertical-align:top/bottom
基本表现类似,只是一个"上"一个"下"因此和在一起讲
定义具体如下:
- 元素底部或者说当前行框盒子的顶部对齐
- table-cell 元素底部padding边缘和表格行的顶部对齐
如果是内联元素,则和这一行高度最高的内联元素的顶部对齐
如果说display计算值是table-cell的元素的话,我们不妨脑补成"<td>" 元素 则和'<tr>'元素上边缘对齐!
其实bottom的话,和top正好相反!
并且需要注意的是,内联元素的上下边缘对齐的这个"边缘"是当前"行框盒子"的上下边缘,并不是块状容器的上下边缘!
其实在该属性中的top和bottom值可以说是最容易理解的了vertical-align属性值了,并且对应的表现也相当的稳定! 不会出现难以理解的现象! 常常在实际开发的过程中用到!
05|vertical-align:middle与近似垂直居中
其实在我们日常开发中的line-height和对应的vertical-align所实现的垂直居中,其实都是"近似垂直居中"! 原因与vertical-align:middle的定义相关!
- 内联元素:元素的垂直中心点和行框盒子基线往上1/2 x-height处对齐
- table-cell元素:单元格填充盒子相对于外面的表格行居中对齐!
基本上所有的字体当中,字符x的位置都是偏下一点儿的,并且是字号越大偏移越明显!
因此导致的vertical-align:middle实现的都是"近似垂直居中!"
其实如果说要实现真正意义上的垂直居中的话,那么需要将X的位置在容器垂直方向的正中间即可!
通常的做法是通过font-size:0;
根据line-height的半行间距上下等分原则,其实这个点就在整个容器的垂直中心位置!
但是我们在日常开发的过程中会发现,font-size的值可能在12px和在14px之间的! 虽然说效果是 "近似垂直居中"但是还是比较难察觉出其中细微的差距的! 因此是否需要实现真正意义上的垂直居中,还需要不断的权衡!
06|深入理解vertical-align文本类属性值
其实文本类属性值就是text-top和text-bottom,其中具体的定义如下:
vertical-align:text-top;盒子顶部与父级内容区域顶部对齐!
vertical-align:text-bottom;盒子的底部与父级内容区域底部对齐!
简单介绍所谓的内容区域:FireFox/IE浏览器文本选中的背景区域,默认状态下的內联文本的背景色区域!
对应的"父级内容区域"其实也就是父级元素当前font-size和font-family下应有的内容区域的大小!
定义可以理解为假设元素后面有一个和父元素font-size,font-family一模一样的文字内容,则vertical-align:text-top;标识元素和这个文字的内容区域的上边缘对齐!
其实讲到这里可以通过预览发现其中的表现在哪里?
预览请见:https://demo.cssworld.cn/5/3-9.php
看到了对应的区别之后呢,来讲讲以下几个明显的优势:
- 文本类属性值的垂直对齐与左右文字大小和高度都没有关系,线性类属性的定位都会受到兄弟内联元素的影响!
- 文本类属性值的垂直对齐可以像素级精确控制,如果是线性雷属性值中的基线和对应的line-height都是无法精确控制垂直居中对齐的! 图文对齐可以控制父元素的font-size 如果是文字对齐可以改变文字的line-height 精确控制对其位置!
其实也从侧面说明了问题,就是CSS设计之初的初衷可能非常的简单,但是结果呢可能却满天飞! 有些属性值应该有大成,实际却无人问津! (vertical-align中的文本类属性的属性值就是之一!)
其中主要的原因如下:
- 使用场景缺乏 当前的CSS重构主要以"精致布局"为主,对齐文本的场景相比旧时代要少很多!
- 文本类垂直对齐理解成本高 一般人可能会用margin定位或者说relative,资深一点可能会用vertical-align数值的方式进行调整,但是呢对应的文本类属性值却很少用,"难以理解" 不方便!
- 内容区域不直观并且内容区域的"易变" 现在实际上对外的项目都要求 精确布局并且像素级还原, 但是内容区域本身默认是看不见的, 并且 内容区域大小是默认和字体font-family相关的,如果说在不同的平台上面运行的话,现实是不同的,内容区域的不同会导致布局对齐的位置也不同,产生了对应的“不兼容”,如果说对视觉要求较高的话,该问题就比较严重了!
这样一来 文本类属性在理论上面强大,但是如果说应用到实际层面开发中的话使用价值却非常有限!
07|简单了解vertical-align上标下标类属性值
在vertical-align下标类属性值指的就是sub和super两个值!对应的就是下上标!
在HTML中有<sub>
和<sup>
两种标签,语义上其实和我们的sub和super其实是一致的!也是上下标的关系!
其实他们两对不一般啊,sup标签默认的vertical-align属性值是vertical-align就是super,sub对应的也就是sub!
ProbeDream<sup>123</sup> //其实就是 ProbeDream123 其中的123在ProbeDream右上角!
ProbeDream<sub>456</sub> //其实也就是ProbeDream456 其中的456在ProbeDream左下角!
基本上所谓的vertical-align上下标属性值的实际应用价值也就只有这么点了! 通过下面的定义就知道了:
- vertical-align:super; 提高盒子的基线到父级合适的上标基线位置!
- vertical-align:sub; 提高盒子的基线到父级合适的下标基线位置!
其中在定义中的合适的意思就显得有点模棱两可了,就非常让人蛮茫然!与此同时,我们还要注意,vertical-align上下标属性值并不会改变对应元素的文字大小,更不要被 sub和sup标签给误导了! 因为这两个HTML标签的默认的font-size为smaller!
- 无处不在的vertical-align
算是对之前内容的一个必要的总结,对于内联元素,有一个"幽灵空白节点"和"无处不在的vertical-align属性"
虽然说同属性线性雷属性值,但是top/bottom和baseline/middle却是完全不同的两个帮派,前者是看边缘和看盒子,但是后者是和字符x打交道!
并且与此同时还需要了解内联盒模型,不同属性值定义完全不同,且很多属性table-cell元素有着不同的定义,同时最终表现与字符x,line-height,font-size,font-family属性密切相关! 需要对这些属性有比较深入的了解!
在本文中示例的展示都是单属性值和默认值baseline如何作用的,但是实际开发的时候会经常出现两个内联元素同时设置baseline意外属性值的情况,但是实际上, vertical-align个类属性值并不会存在互相冲突的情况!但是某个vertical-align的属性值确实会影响某个元素的表现,但是并不是直接的,因此我们在分析复杂场景的时候,仅需要套用定义分析当前的vertical-align值的作用就行了!
基于vertical-align属性的水平垂直居中的弹框!
预览请见:https://demo.cssworld.cn/5/3-10.php
其中相较于传统的JavaScript精确计算弹框的位置,有以下优点:
1.节省了很多无谓的JavaScript代码,并且不需要浏览器进行热size事件之类的处理,弹框内容动态变化的时候,无需重新定位!
2.性能更快,喧嚷速度更快,浏览器内置CSS的即时渲染器比JavaScript处理的更好!
3.可以非常灵活控制垂直居中的比例
4.容器设置了overflow:auto可以实现弹框高度超过一屏是依然能够看见屏幕外的内容,传统实现方法则比较尴尬!