Chrome字体显示模糊

65

让我眼睛疲劳了!

在IE和Firefox中看起来很好

enter image description here

Chrome(上图)

在运行版本为39的Chrome中,只有在模态框中出现模糊,更改字体系列不会产生任何差异。

以下是浏览器呈现的CSS(针对标签“Start”)

box-sizing: border-box;
color: rgb(85, 85, 85);
cursor: default;
display: block;
float: left;
font-family: sans-serif;
font-size: 12px;
font-weight: 600;
height: 24px;
line-height: 17.142858505249px;
margin-bottom: 0px;
margin-top: 0px;
min-height: 1px;
padding-left: 15px;
padding-right: 15px;
padding-top: 7px;
position: relative;
text-align: right;
visibility: visible;
width: 89.65625px;

是浏览器还是CSS的问题?

--更新--

好的,看起来是CSS的问题。

.md-modal {
    position: fixed;
    top: 50%;
    left: 50%;
    width: 50%;
    max-width: 630px;
    min-width: 320px;
    height: auto !important;
    z-index: 2000;
    visibility: hidden;
    -webkit-backface-visibility: hidden;
    -moz-backface-visibility: hidden;
    backface-visibility: hidden;
    -webkit-transform: translateX(-50%) translateY(-50%); <--- This line
    -moz-transform: translateX(-50%) translateY(-50%);
    -ms-transform: translateX(-50%) translateY(-50%);
    transform: translateX(-50%) translateY(-50%);
}

但是如果我把它拿出来,我的模态框就不再居中了?


3
你能否将你的标记粘贴到JSFiddle或其他地方,以查看是否可以在那里复制?仅凭样式无法复制这个问题。 - David Lerner
你可以尝试使用类似 -webkit-font-smoothing: none; 的东西。 - Chad
嘿,已更新主贴。 - D-W
我在布局后使用矩阵归一化:https://dev59.com/X14c5IYBdhLWcg3w7t7E#42256897 - Miguel
@D-W 将 position: relative; 更改为 position: unset; - Fábio Zangirolami
显示剩余6条评论
25个回答

46

我通过从Y轴的值中减去0.5px来解决了这个问题。因此,不要这样做:

transform: translateX(-50%) translateY(-50%);

我做了这个:

transform: translateX(-50%) translateY(calc(-50% - .5px));

这对我解决了问题,我觉得这个方案比调整百分比或者使用JavaScript更加简洁。


这对我也起作用了。尝试使用perspective(),带有translateY(50.1%),使用scale(1.0, 1.0)和其他解决方案。 - Vincent
2
我找到的最精彩的答案 :) - scniro
1
这对我来说没有解决问题(Chrome 75)。 - Jake Reece
.4像素更锐利 :) - Coffee bean
1
不确定为什么这个有那么多赞,这只是在元素高度恰好是奇数像素(因此-50%不是整数)时才会修复它。如果它恰好是偶数像素,则会产生完全相反的结果。因此,结果将根据浏览器窗口的大小而异。 - cdauth
显示剩余3条评论

37

在应用翻译变换到我的元素后,我在谷歌浏览器上遇到了同样的问题。这似乎是Chrome浏览器上的一个bug。唯一有效的方法是:

#the_element_that_you_applied_translate_to {
  -webkit-filter: blur(0.000001px);
}

另一个解决方案是打开平滑字体渲染:

#the_element_that_you_applied_translate_to {
  -webkit-font-smoothing: antialiased;
}

3
非常感谢你!!!我一直面临这个问题,但一直没有好的解决方案。 - Andrew Rasmussen
3
优秀的解决方案含有模糊效果,这是唯一真正修复问题的方法。但从昨天开始似乎不再有效了。问题仅出现在translateY() 上,这是导致内容模糊的原因。我发现只有元素高度为奇数时,内容才会模糊。(225px=模糊,224px=清晰)可惜开发人员多年来都无法解决这个问题!!!至少 Chrome 完全支持 flex。如果您的 HTML 结构允许父级>子级(居中对齐),并且不介意 IE,请尝试以下内容: https://philipwalton.github.io/solved-by-flexbox/demos/vertical-centering/ - Nomak22
我同意@nomak22的解释。您可以通过更改文本的行高来进行检查。 - Jaswinder
1
在评论时根本不起作用。Win10上的Chrome。无论值是什么,-webkit-font-smoothing都绝对没有任何效果。而模糊滤镜只会像应该的那样使事物变模糊,而我认为我们正在尝试消除模糊? - Matvey Andreyev

33

4
哇…这修复的原因是什么呢?还是说这是设计的一个��性? - Spaceman
3
我不清楚这个修复方法的作用,你的例子完全覆盖了他想要的转换。transform: translateZ(0)是最后应用的规则,因此X/Y转换被忽略。这会解决模糊问题,因为X/Y转换是问题的根源。对于那些尝试居中的人来说,那些X/Y转换一定要保留。 - helion3
3
如果确实想要实现translate(-50%,-50%)且不产生模糊文本,则这不是解决方法 - Roko C. Buljan
我认为这个答案已经过时了。我在运行的Chrome版本中不再看到这个问题。这个问题在上面的fiddle中也没有出现。 - JSuar
1
检查这个变换矩阵归一化:https://dev59.com/X14c5IYBdhLWcg3w7t7E#42256897 - Miguel
显示剩余3条评论

15

唯一的正确解决方法:

这个问题是由于使用CSS转换中的“%”值来对齐div而导致的。这会产生小数次像素值,而您的屏幕无法正确呈现。解决方法是规范化生成的变换矩阵

对于不执行转换动画的固定div可能效果更好。但如果您执行动画,可以在此函数的结束后回调来更正最终状态。

enter image description here

因此: matrix (1,0,0,1,-375,-451.5) 将变为 matrix (1,0,0,1,-375,-451)

我在jQuery的.show()之前调用此方法...或者只在应用程序中调用一次(取决于您的情况),您可能还需要在调整大小事件等上调用此方法。

function roundCssTransformMatrix(element){
        var el = document.getElementById(element);
        el.style.transform=""; //resets the redifined matrix to allow recalculation, the original style should be defined in the class not inline.
        var mx = window.getComputedStyle(el, null); //gets the current computed style
        mx = mx.getPropertyValue("-webkit-transform") ||
             mx.getPropertyValue("-moz-transform") ||
             mx.getPropertyValue("-ms-transform") ||
             mx.getPropertyValue("-o-transform") ||
             mx.getPropertyValue("transform") || false;
        var values = mx.replace(/ |\(|\)|matrix/g,"").split(",");
        for(var v in values) { values[v]=v>4?Math.ceil(values[v]):values[v]; }

        $("#"+element).css({transform:"matrix("+values.join()+")"});

}

并将其称为

roundCssTransformMatrix("MyElementDivId");
$("#MyElementDivId").show();

漂亮,不是吗?

如果您需要在调整大小时进行更新,可以使用以下方法:

$( window ).resize(function() {
  roundCssTransformMatrix("MyElementDivId");  
});
为了让这个方法生效,所有的父元素都必须“对齐/归一化”,因为如果比如说body左边是10.1像素,而子元素是10像素,问题不会消失,因为父元素在矩阵上仍有小数残留。所以你必须将这个函数应用于每个作为父元素且使用transform的元素。
你可以在此处查看该实时脚本:https://jsbin.com/fobana/edit?html,css,js,output

我本来希望有一个纯CSS的解决方案,但这个也可以。我不能使用这里的其他建议,因为我正在将此CSS用于页面上的多个元素。一些元素在给定-50%偏移量时具有圆形数字,而不是所有元素都是如此。因此,将其设置为calc(-50% - .5px)可以修复某些元素,但会破坏其他元素。 - Jespertheend

9
感谢提供CSS示例。看起来,translateX(50%)translateY(50%)正在计算具有小数位(例如0.5像素)的像素值,从而引起了子像素渲染。
虽然有许多解决方案,但如果您想保留文本的质量,那么您目前最好的解决方案是在.md-modal上使用-webkit-font-smoothing: subpixel-antialiased;来强制渲染Webkit浏览器(如Chrome和Safari)中的呈现状态。

1
嘿,谢谢你的回复。我添加了那行代码,但是很遗憾没有任何影响。 - D-W
@D-W 你找到解决方案了吗?你有 Codepen 或 jsFiddle 可以让我们查看吗? - josh1978
2
我对 translateX(x) 的值使用了 Math.round(),现在渲染非常流畅。谢谢。 - Mak
2
@mak - 您能提供一些更具体的细节,说明您如何使用 Math.round() 实现解决方案吗? - GWR
我点赞这个答案不是因为解决方案对我有用,而是因为第一段让我清楚了这个问题的原因。谢谢。 - Akza

5
我通过删除以下这些行来解决了这个问题:
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;

5
我花了一些时间来寻找一个解决方案,而不让我感到烦恼,所以我会在这里发布它。
对我而言,问题是子div具有width和height属性的组合会导致问题。
当我改变height为另一个值时,它就可以正常工作了!
这可能与其他答案有关,但我不想使用任何JS或更改transform属性来修复它。
这里是一个实时示例:JSFIDDLE

我对这个如何工作感到困惑,但感谢分享。我会尝试一下。 - captainrad

3

如果你想让某个元素居中,最好使用flexbox。它可以帮助你定位而不会使文本模糊。

将以下内容添加到要居中的元素的父级div中:

display: flex;
justify-content: center;
align-items: center;

希望这能帮到您。

2
似乎Chrome 78仍存在这个bug:https://bugs.chromium.org/p/chromium/issues/detail?id=521364
在之前的答案基础上,我发现以下CSS可以让翻译模态框的显示效果更加清晰:
transform: translate(calc(-50% - .4px), calc(-50% - .4px));

编辑: 为了兼容IE11:

transform: translateX(-50%) translateX(-0.4px) translateY(-50%) translateY(-0.4px);

1
对于模态框,这个CSS会有帮助:

-webkit-transform: translate3d(-50%, -51%, 0);
-moz-transform: translate3d(-50%, -51%, 0);
transform: translate3d(-50%, -51%, 0);

将Y轴位置从50%改为51%,这对我的情况有帮助。如果您有不同的定位,请试着调整,但通常1%的上下偏移可以解决模糊的内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接