企业IE11迁移指南:由IE11“Natural Metrics”造成的页面布局问题
2016年8月20日

升级至IE11后网页布局破坏最常见的原因是:IE11使用了较新的文档模式来渲染页面。但有时候会发现一个页面即使使用了相同的文档模式,IE11中显示的布局仍然被破坏了,这可能是由于IE11使用了一种全新的字体渲染模式:natural metrics,在IE11之前IE都是使用传统的gdi metrics

问题表现

下面这段网页代码是在IE7、8年代开发的。开发者为了将一段文字显示在一行内指定了DIV容器的宽度。为了保证新版本IE浏览器能兼容该页面,开发人员还特地使用X-UA-Compatiblemeta标签来指定使用IE7文档模式。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=7">
    <style>
        #top-box {
            background: #ccc;
            padding: 5px;
            width: 330px;
        }
    </style>
</head>
<body>
    <div id="top-box">Single line text appears in a fixed width DIV container.</div>
</body>
</html>

该页面在IE8到IE10中都显示正常:

然而升级至IE11后,文字变成了2行:

问题原因

默认情况下,IE11使用了一种叫做natural metrics的字体渲染引擎。Natural metrics使用了像素间距来提供更加适宜阅读的文字渲染效果。之前IE浏览器使用的字体渲染为传统的GDI metrics。从下图我们可以看出natural metrics渲染的字体更加顺滑,不像GDI metrics锯齿感那么明显。

由于之前开发是基于老版本的IE浏览器,330px的宽度是基于GDI metrics计算出来的。很显然,在 natrual metrics中,330px的宽度已经不足以将这段文字显示在一行内了。

相较于GDI metricsnatural metrics显示的每一个文字会更宽一些。我们可以通过下面的代码来测量文字:“ABC”在两种模式下的宽度。

<span id="span">ABC</span>
<br/>
<button id="show-offset" onclick="showoffset()">Show offset</button>
<script>
    function showoffset() {
        alert(document.getElementById('span').offsetWidth);
    }
</script>

在IE8到IE10中(GDI metrics),“ABC”的宽度为32。

在IE11中(natural metrics),“ABC”的宽度为33。

解决方案

客户端方案

把网站加入本地Intranet站点。IE11对于本地Intranet的站点依然使用GDI metrics来渲染字体。

代码方案

加入<meta http-equiv="X-UA-TextLayoutMetrics" content="gdi" />meta标签以强制浏览器使用GDI metrics来渲染文字。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=7">
    <meta http-equiv="X-UA-TextLayoutMetrics" content="gdi" />
    <style>
        #top-box {
            background: #ccc;
            padding: 5px;
            width: 330px;
        }
    </style>
</head>
<body>
    <div id="top-box">Single line text appears in a fixed width DIV container.</div>
</body>
</html>

开发建议

不同的浏览器有不同的字体渲染引擎、方式。你基于一个浏览器计算得出的大小并不一定适用于另一个浏览器。所以我们尽可能不要指定文本容器的宽度,而让文本自适应于容器中,如果一定要指定宽度,那么尽量在文本周围留有一些空间避过于紧密的布局模式。

参考