将font-family设置为sans-serif会导致jQuery计算出错误的outerWidth

时间:2013-11-20 04:40:57

标签: jquery css internet-explorer firefox width

不知何故,仅仅在以下文档中设置font-family: sans-serif样式会导致li标记内容包含在IE 11.0.9600.16438和FireFox 25.0.1中,但不包含在Chrome 31.0.1650.57中。当我注意到使用SimpleModal 1.4.4时,一些li标签不必要地换行时,我首先注意到了它。我设法通过添加,逐个,标记和CSS样式到独立文档来重现这一点。最后,我使用jQuery的outerWidthouterHeight方法来检索计算出的大小,我已经确认这是SimpleModal使用的。

编辑:为了清楚起见,我使用outerWidthouterHeight结果在模态对话框中设置显式大小。这就是SimpleModal所做的事情,它对于对话框的正常运行显然至关重要。我的问题是在SimpleModal的上下文中,但我已经缩小了对jQuery的奇怪行为。

这是标记没有 font-family: sans-serif

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <title></title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
        <style>
            * { -moz-box-sizing: border-box; box-sizing: border-box; font-size: 16px; font-weight: normal; font-style: normal; font-family: sans-serif; }
            ul { margin: 0 0 0.5rem; padding: 0 0 0 2rem; list-style: disc; }
            p { margin: 0 0 0.5rem 0; padding: 0 }
            .simplemodal-wrap { height: 100%; outline: 0; width: 100%; overflow: visible; }
            .simplemodal-data { background-color: #ddd; padding: 1rem; }
        </style>
    </head>
    <body>
        <main>
            <div class="simplemodal-container" style="position: fixed; left: 25px; top: 75px; z-index: 1002;">
                <div class="simplemodal-wrap">
                    <div class="simplemodal-data">
                        <p>Lorem ipsum Lorem ipsum Lorem ipsum:</p><ul><li>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum</li><li>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum</li><li>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum</li><li>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum </li><li>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum</li><li>Lorem ipsum Lorem ipsum Lorem ipsum </li></ul><p>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum :</p><ul><li>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum </li><li>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum </li></ul>
                    </div>
                </div>
            </div>
        </main>
        <script>
            $(function() {
                var sc = $(".simplemodal-container");
                var outerWidth = sc.outerWidth(true);
                var outerHeight = sc.outerHeight(true);

                $("main").append("<div>outerWidth(true) x outerHeight(true):<br>" + outerWidth + " x " + outerHeight + "</div>");

                sc.css({ width: outerWidth, height: outerHeight });
            });
        </script>
    </body>
</html>

所有三种浏览器的搜索结果都是正确的(这里以Chrome为例):

Chrome

现在,只需将font-family: sans-serif;添加到*选择器并刷新所有三个浏览器即可。突然,宽度计算错了!

IE 11 FireFox 25.0.1

在IE和FireFox中将宽度增加一个像素会导致li标记不再包裹。

这里发生了什么?这是字体大小计算的某种舍入错误吗?

编辑:这是我最终在第553行添加到jquery.simplemodal-1.4.4.js的代码:

// jQuery truncates subpixel width and height calculations
// Fixed incorrect wrapping in Mozilla
var userAgent = navigator.userAgent.toLowerCase();
if (userAgent.length >= 7 && userAgent.substring(0, 7) === "mozilla") {
    dw++;
    dh++;
}

这样的黑客,但显然是必然的。 :(

1 个答案:

答案 0 :(得分:1)

jQuery的outerWidth API被设计破坏了:它返回一个整数个CSS像素。

在执行亚像素文本整形和定位的浏览器中(Firefox和IE会这样做而Chrome不会),一般来说,文本字符串的宽度不会是整数个CSS像素。即使在Chrome中,如果你有一个高DPI屏幕,那么一个CSS像素对应于两个或更多设备像素,一串文本的宽度最终可能是一个非整数的CSS像素。

然后jQuery有效地采用实际宽度并向下舍入到整数。这意味着如果文本不是整数像素宽,则得到的数字太小。

您可能想要做的是使用getBoundingClientRect()来获取框的实际尺寸而不进行舍入。并向jQuery作者抱怨jQuery没有提供方便的API。 ;)