深入剖析 CSS:字体度量、行高和垂直对齐( 四 )

深入剖析 CSS:字体度量、行高和垂直对齐
文章图片
每个子项都对齐 , 就好像其行框以不可见的零宽度字符开头一样基线对齐被搞砸了 , 但是为了救援呢?正如您在规范中读到的那样 , “将框的垂直中点与父框的基线加上父框的x高度的一半对齐” 。 基线比率以及x高度比率不同 , 因此中间对齐也不可靠 。 在大多数情况下 , 最糟糕的情况从来都不是真正的“中间” 。 涉及的因素太多 , 无法通过CSS设置(x高度 , 上升/下降比率等)vertical-align:middlemiddlemiddle
顺便说一句 , 还有其他4个值 , 在某些情况下可能很有用:
vertical-align:top/bottom与线框的顶部或底部对齐
vertical-align:text-top/text-bottom与内容区的顶部或底部对齐
深入剖析 CSS:字体度量、行高和垂直对齐
文章图片
垂直对齐:顶部、底部、文本顶部和文本底部但要小心 , 在所有情况下 , 它都会对齐虚拟区域 , 因此不可见的高度 。 看看这个使用的简单示例 。 不可见的行高可能会产生奇怪但不令人惊讶的结果 。 vertical-align:top
深入剖析 CSS:字体度量、行高和垂直对齐
文章图片
垂直对齐最初可能会产生奇怪的结果 , 但在可视化行高时是预期的最后 , 还接受相对于基线提高或降低框的数值 。 最后一种选择可能会派上用场 。 vertical-align
CSS很棒
我们已经讨论了如何一起工作 , 但现在的问题是:字体指标是否可以用CSS控制?简短的回答:不 。 即使我真的希望如此 。 无论如何 , 我认为我们必须玩一点 。 字体指标是恒定的 , 所以我们应该能够做一些事情 。 line-heightvertical-align
例如 , 如果我们想要一个使用双体船字体的文本 , 其中大写高度正好是100px高 , 该怎么办?似乎可行:让我们做一些数学运算 。
首先 , 我们将所有字体指标设置为CSS自定义属性4 , 然后进行计算以获得100px的大小写高度 。 font-size
p{/*fontmetrics*/--font:Catamaran;--fm-capitalHeight:0.68;--fm-descender:0.54;--fm-ascender:1.1;--fm-linegap:0;/*desiredfont-sizeforcapitalheight*/--capital-height:100;/*applyfont-family*/font-family:var(--font);/*computefont-sizetogetcapitalheightequaldesiredfont-size*/--computedFontSize:(var(--capital-height)/var(--fm-capitalHeight));font-size:calc(var(--computedFontSize)*1px);}
深入剖析 CSS:字体度量、行高和垂直对齐
文章图片
大写高度现在为100px高很简单 , 不是吗?但是 , 如果我们希望文本在视觉上位于中间 , 以便剩余空间均匀地分布在“B”字母的顶部和底部 , 该怎么办?为了实现这一点 , 我们必须根据上升/下降比率进行计算 。 vertical-align
首先 , 计算和内容区域的高度:line-height:normal
p{…--lineheightNormal:(var(--fm-ascender)+var(--fm-descender)+var(--fm-linegap));--contentArea:(var(--lineheightNormal)*var(--computedFontSize));}
然后 , 我们需要:
从大写字母底部到底部边缘的距离
从大写字母顶部到顶部边缘的距离
这样:
p{…--distanceBottom:(var(--fm-descender));--distanceTop:(var(--fm-ascender)-var(--fm-capitalHeight));}
我们现在可以计算 , 即距离乘以计算的之间的差值 。 (我们必须将此值应用于内联子元素)vertical-alignfont-size
p{…--valign:((var(--distanceBottom)-var(--distanceTop))*var(--computedFontSize));}span{vertical-align:calc(var(--valign)*-1px);}
最后 , 我们设置所需的并进行计算 , 同时保持垂直对齐:line-height
p{…/*desiredline-height*/--line-height:3;line-height:calc(((var(--line-height)*var(--capital-height))-var(--valign))*1px);}