爆炸
最近 UI 走查, 发现页面中所有包含文字区块的高度与设计稿中的高度完全不一致, 然后 UI 妹子就爆炸了!
找了一下原因, 发现是由于 UI 设计稿中设计的文字大部分是
font-size:24px;line-height:24px
, 代码实现时为了不至于每处都写一遍字体大小, 故直接在根节点上统一设置字体与字体大小为 24px, 小部分不一致的地方再单独设置字体大小, 从而忽略了设置 line-height 为字体的高度. 造成的结果就是文字所在的行的行高高于设计稿中的行高.
为什么文字行高与字体大小不相等呢?
翻了一下 line-height 的 <a href="https://www.w3.org/TR/CSS2/visudet.html#propdef-line-height"> 官方说明 </a>, 如下所示:
这里写图片描述
文档里说 line-height 的默认值为 normal, 给 normal 的推荐设置值为 1.0 到 1.2 之间. 相当于如果设置了字体的大小而不设置 line-height, 那么行高默认就为字体的 1.0-1.2 之间的一个倍数.
那么, 这个倍数到底具体是多少呢?
在 chrome 的控制台里跟踪了一下, 看到项目中引入了 normalize.css 来初始化浏览器的默认 css 样式. 其中, 就设置 html 的 line-height 为 1.15.
为什么 normalize.css 设置 line-height 默认为 1.15?
翻了一下 github 中 normalize.css 的 issues, 在 593 号 issues 里找到了答案, 地址在 < a href="https://github.com/necolas/normalize.css/issues/593"> 这里 </a>.
大致过程是这样的, 有人发现相同字体与大小的文字在不同环境中 line-height 的值是不一致的, 接着, 就有人在 crossbrowsertesting 上做了个测试, 得出的结论就是这个问题的的确确存在, 而且差异还特别大
When the font size was 100px, the most common line height was 115px. However, results varied from 101px on Mac Firefox to 136px on Android Chrome.
最终, 由于大部分的行高都为 115px, 所以, 为了解决不同环境中相同字体与字号的文字行高不一致的问题, 推荐设置默认 line-height 为 1.15
看到这里, 想到一个问题, 既然显示设置 line-height 为 1.15 是为了解决环境兼容的问题. 那么, 为什么不设置 line-height:1 即解决兼容问题, 又解决由于行高放大与 UI 设计稿不符的问题? .
设置 overflow:hidden 字体显示不全的问题
当设置文字 line-height:1 后, 再设置文字所在的容器 overflow:hidden 很容易复现文字显示不全的问题, 比如下面:
<span style="font-size:100px;line-height:1;overflow:hidden;border:1px solid #ddd;display:inline-block">dphyTxg</span>
代码如下:
<span style="
font-size:100px;
line-height:1;
overflow:hidden;
border:1px solid #ddd;
display:inline-block">dphyTxg</span>
注: 这里可以使用 div 演示, 然后去掉 display:inline-block. 使用 div 发现不知道为毛 markdown 里的样例乱了...
为什么设置行高与字体大小一致文字会显示不全?
到这里, 才真正进入到深层次的原因探究.
对于这个问题, 需要先了解字体度量, 引用一下其它的文章说明, 如下所示:
这里写图片描述
- <a href="https://zhuanlan.zhihu.com/p/25808995"> 原文地址 </a>
- <a href="http://iamvdo.me/en/blog/css-font-metrics-line-height-and-vertical-align">Deep dive CSS: font metrics, line-height and vertical-align</a>
- <a href="http://designwithfontforge.com/zh-CN/The_EM_Square.html">EM Square</a>
- <a href="https://fontforge.github.io/en-US/">FontForge</a>
简要解释为如下几点:
我们设置 font-size 的高度实际上是对应字体的 EM square 部分
字体在设计时可以超出 EM square 部分
字体实际设计与 EM square 部分一致时, line-height:normal 与 line-height:1 相等
从上图中可以看到,
ascender+descender>Em Size
即 1100+540>1000, 此时 line-height:1.64, 所以 100px 的文字默认的行高为 164px
样例分析
下面就以 window 环境下的默认字体微软雅黑为例实际看看 line-height 的计算.
- <h1 id="font" style="line-height:normal;font-size: 100px;font-family: 微软雅黑">h1</h1>
- <p>line-height: <code id="o1" style="font-size: 50px"></code></p>
- <script>
- document.getElementById('o1').textContent = window.getComputedStyle(document.getElementById('font')).height;
- </script>
代码如下:
- <h1 id="font" style="line-height:normal;font-size: 100px;font-family: 微软雅黑">h1</h1>
- <p>line-height: <code id="o1" style="font-size: 50px"></code></p>
- <script>
- document.getElementById('o1').textContent = window.getComputedStyle(document.getElementById('font')).height;
- </script>
从上面可以看到微软雅黑 100px 情况在, 在 windows 下行高显示为 132px. 通过 FontForge 来核对一下看看是不是这样的.
这里写图片描述
从上图中可以看到, 使用
(ascender+descender)/Em Size
, 即
(2167+536)/20481.32
, 也就是 line-height 为 1.32.
结论
line-height:normal 的值跟字体有关系, 相同字体在不同环境也不一样
当 line-height 设置的值小于默认的值时就会存在显示不全的问题
normalize.css 设置 line-height 默认为 1.15, 当字体 line-height 的 normal 大于 1.15 就会存在文字显示不全的问题
要解决字体在不同平台 line-height 不一致的问题, 需根据具体字体, 选择 normal 在不同平台上的最大值设置
来源: http://www.jianshu.com/p/15ebb91323d9