Chrome 字体显示模糊

Posted

技术标签:

【中文标题】Chrome 字体显示模糊【英文标题】:Chrome Font appears Blurry 【发布时间】:2015-02-07 17:02:30 【问题描述】:

它在我的眼睛里!

在 IE 和 Firefox 中看起来不错

Chrome(上)

运行 39 版的 chrome, 仅在模态框中显得模糊,如果我更改字体系列,则没有任何区别。

这是浏览器呈现以下内容的 CSS(用于标签“开始”)

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%);

但是,如果我将其取出,我的模态不再居中?

【问题讨论】:

父元素上是否有任何 CSS 转换?看起来它被定位在一个像素的小数点上。 你能把你的标记粘贴到 JSFiddle 或其他东西中,看看它是否在那里复制吗?单独的样式不允许我复制这个 你可以试试-webkit-font-smoothing: none; @BurpmanJunior 嘿,不是 CSS 专家,我在找什么? 嘿更新了主帖 【参考方案1】:

感谢 CSS 示例。似乎translateX(50%)translateY(50%) 正在计算一个带小数位的像素值(例如,0.5px),这会导致子像素渲染。

对此有很多修复,但如果你想保持文本的质量,你现在最好的解决方案是在 .md-modal 上使用 -webkit-font-smoothing: subpixel-antialiased; 来强制 Chrome 和 Safari 等 webkit 浏览器的呈现状态。

【讨论】:

谢谢您的回复,我添加了那行,但我担心没有影响 @D-W 你找到解决方案了吗?你有 Codepen 或 jsFiddle 我们可以看看吗? I Math.round() 为我的代码添加了 translateX(x) 值,现在渲染很流畅。谢谢。 @mak - 你能否提供更多关于你如何使用 Math.round() 实现解决方案的详细信息?【参考方案2】:

This fiddle tests out a few different solutions 来自:

CSS transition effect makes image blurry / moves image 1px, in Chrome? WebKit: Blurry text with css scale + translate3d http://www.useragentman.com/blog/2014/05/04/fixing-typography-inside-of-2-d-css-transforms/

测试输出

修复 0

-webkit-transform: translateZ(0);
transform: translateZ(0);

修复 3

-webkit-transform: translate3d(0,0,0) !important;
transform: translate3d(0,0,0) !important;

【讨论】:

哇...有什么原因可以解决这个问题。或者这是一个设计的功能。 我不清楚这是如何解决的,您的示例完全覆盖了他想要的转换。 transform: translateZ(0) 是应用的最后一条规则,因此忽略 X/Y 转换。这解决了模糊问题,因为 X/Y 变换是问题的根源。对于那些试图居中的人,那些 x/y 变换必须保留。 如果它正是 translate(-50%, -50%)(+ 没有模糊的文本)想要达到的目标,这 不是解决方法 我们需要一个真正的修复,这是谷歌解决的问题吗?还是这个简单的“如果有人想使用转换就无法修复”? 检查这个变换矩阵归一化***.com/a/42256897/1834212【参考方案3】:

对于模态框,这个 css 会有所帮助:

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

不要将 Y 轴设置为 50%,而是设置为 51%。这对我的 cse 有帮助。 如果您有不同的定位,请尝试一下,但通常 1% 的上/下可修复模糊的内容。

【讨论】:

【参考方案4】:

在将翻译转换应用于我的一个元素后,我在 chrome 上遇到了同样的问题。这似乎是chrome上的一个错误。唯一对我有用的是:

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

另一种解决方案可以打开平滑字体渲染:

#the_element_that_you_applied_translate_to 
  -webkit-font-smoothing: antialiased;

【讨论】:

谢谢* 100000000。这个问题我已经面对很久了,没有好的解决方案。 具有模糊效果的出色解决方案 .. 只有真正解决了这个问题。 ...但是从昨天开始,这似乎不再起作用了。问题仅在于 translateY() 这就是导致内容模糊的原因。我发现只有当元素的高度是奇数时,内容才会模糊(225px = 模糊,224px = 应该是锐利的)。遗憾的是开发人员多年来无法解决此问题!!!至少 chrome 完全支持 flex,如果你的 html 结构允许 parent > child(centerend) 并且你不关心 IE 试试这个:philipwalton.github.io/solved-by-flexbox/demos/… 我同意@nomak22的解释。您可以通过更改文本的行高来检查它。 在发表此评论时根本不起作用。 Win10上的Chrome。 -webkit-font-smoothing 无论值是什么,都绝对没有效果。模糊滤镜只是将事物模糊化,而我认为我们正在尝试消除模糊?【参考方案5】:

我最终通过删除这些行来解决这个问题:

-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;

【讨论】:

【参考方案6】:

向我的模糊元素(使用导致模糊的 transformX)的父元素的父元素添加 CSS 过渡实际上消除了令人讨厌的模糊。

【讨论】:

【参考方案7】:

解决此问题的唯一正确方法:

这个问题源于使用 % 值来对齐 div 使用 css 转换的事实。这会导致您的屏幕无法正确渲染的小数子像素值。解决方案是对生成的变换矩阵进行归一化。

对于不做转换动画的固定 div 可能会更好。但是如果你做动画,你可以使用这个函数的结束后回调来纠正最终状态。

所以: 矩阵 (1,0,0,1,-375,-451.5) 会变成 矩阵 (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");  
);

为此,所有父级必须“对齐/规范化” 因为如果你的身体有 x=10.1px 离开,并且 孩子是 10px .. 这个问题不会消失,因为父母在他们的矩阵上有剩余的小数 因此,您必须将此函数应用于作为父元素的每个元素,并且 使用变换。

您可以在此处查看此实时脚本:https://jsbin.com/fobana/edit?html,css,js,output

【讨论】:

我希望有一个仅 css 的解决方案,但这可以。我无法使用此处的任何其他建议,因为我将此 css 用于页面上的多个元素。当给出 -50% 的偏移量时,一些但不是所有元素都有一个整数。因此将其设置为 calc(-50% - .5px) 会修复一些元素,但会破坏其他元素。【参考方案8】:

我通过从 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) 和其他解决方案。 我在一段时间内找到的最关键的答案:) 你怎么能确定它会在所有设备上得到修复? 这并没有解决我的问题(Chrome 75)。 - .4px 更清晰 :)【参考方案9】:

我花了一段时间才找到一个我不会费心使用的解决方案,所以我会在这里发布。

对我来说,问题是子 div 具有 widthheight 属性,它们的组合导致了问题。

当我将height 更改为另一个值时,它就起作用了!

这可能与其他答案有关,但我不想使用任何 JS 或更改转换属性来修复它。

这是一个活生生的例子:JSFIDDLE

【讨论】:

我对它的工作原理感到困惑......但感谢分享。我会试试这个。【参考方案10】:

类似的问题发生在我身上。

我尝试了所有建议的方法,但都没有奏效。但是,最后我解决了它。 由于具有font-weight:600 或更多的谷歌浏览器存在问题。 尝试将字体系列更改为font-family:"Webly Sleek SemiBold","Helvetica";

font-weight 属性可以正常工作。

【讨论】:

【参考方案11】:

另一个原因可能是您没有提供您正在使用的所需字体粗细。

例如,如果您想同时使用 Lato 或 Roboto,您希望包含的不仅仅是标准重量。如果您使用的是 Google Font API,则此示例适用:

<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:400,900|Roboto:500,700">

注意:Lato 有 100、300、400、700 和 900 字体粗细,但我必须指定 900 才能让 700 文本变得清晰...不知道为什么。

【讨论】:

【参考方案12】:

目前,我只找到了一个好的解决方案:

transform: translate(-50%, -50.1%)

0.1% - 一般用户看不到这个

希望 chrome 能够修复它 - 该错误自 2014 年以来就存在))))

【讨论】:

【参考方案13】:

如果你不想实现任何特殊的 js 或自定义解决方案,并且你想要实现的唯一目标是让你的 div 居中,并且宽度和高度没有固定大小,你可以简单地使用这个:

position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;

如果其中一个尺寸是固定的,您可以尝试这种方法:

position: absolute;
left: 50%;
translate: transformX(-50%);
top: 0;
bottom: 0;
margin: auto;

它修复了 chrome 中字体模糊的问题。

【讨论】:

【参考方案14】:

如果你想居中,最好使用 flexbox。它将帮助您定位而不会出现模糊的文本。

将此添加到要居中的那个元素的 父 div

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

希望这会有所帮助。

【讨论】:

【参考方案15】:

似乎 Chrome 78 仍然有这个错误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);

【讨论】:

【参考方案16】:

您可以通过以下方式解决此问题:

    transform: inherit;

【讨论】:

【参考方案17】:

我发现解决这个问题的最佳方法是替换所有 transform:translate(-50%,50%) em> 具有替代解决方案的定义。使用任何其他解决方案可能会在您的屏幕上解决它,但不能在另一个屏幕上解决。

变换定义通常用于使元素居中。与其使用变换定义,不如找到另一种方式使元素居中,问题将得到解决。在我们的例子中,我们有一个想要居中的固定 div,最大宽度为 1800 像素,底部设置为 0 像素;

#cntrposition:fixed;left:50%;bottom:0;width:100%;max-width:1800px;transform:translateX(-50%);-ms-transform:translateX(-50%);-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-o-transform:translateX(-50%);text-align:center;

那里有很多定义来涵盖所有浏览器。改成这个来解决它:

#cntrposition:fixed;left:0;right:0;margin:auto;bottom:0;width:100%;max-width:1800px;text-align:center;

代码更少,更简洁,更快,100% 工作,无需编辑任何 HTML。

现在将固定位置 div 居中的定义是:left:0;right:0;margin:auto;

不需要翻译,没有小数点放置div。

【讨论】:

【参考方案18】:

TLDR

几天前我遇到了这个问题。我几乎疯了,试图在 Chrome 中锐化字体。我已阅读此线程中的所有帖子以及所有其他有关在 Chrome 中锐化字体的帖子。即使是“解决此问题的唯一正确方法”的消息也对我没有帮助。有什么帮助?

值得一提的是,问题出现在以下div中:

position: sticky;
left: 16%;

“粘性”属性原来是最大的问题。对于粘性元素,我们将位置设置为“绝对”元素 - 使用“左”、“上”等属性。问题是:“左”不是整数值,字体被渲染得非常模糊, 使用整数会好很多。

解决办法是什么?

position: sticky;    
left: 0;
margin-left: 16%;

仅此而已。 Chrome 将处理百分比“边距”,字体看起来很清晰。

【讨论】:

【参考方案19】:

对于那些仍在试图找到解决方案的人,设置背景出于某种原因为我修复了它。

background: #fff;

【讨论】:

【参考方案20】:

我发现应用 JSuar 建议的 translate3d(0, 0, 0) 修复程序在 Chrome 中有效,但在 Safari 中无效。

在浏览器中起作用的一件事是给我居中的元素(使用transform: translate(50%, -50%))一个均匀的像素宽度——将宽度从 425px 更改为 426px 使文本再次清晰。

【讨论】:

【参考方案21】:

我的网站也遇到了这个问题,使用了类似的设置。 出现此问题是因为 0.5px 差异。 一个简单的解决方法是将顶部属性从 50% 更改为 calc(50% - .5px)

【讨论】:

【参考方案22】:

当元素的宽度和高度不是偶数时,position: fixed;transform: translate(...) 经常会出现此问题。

其中一种解决方案是以编程方式对数字进行四舍五入。示例:

function roundToEven(x) 
  const rounded = Math.round(x)
  return rounded % 2 ? rounded + 1 : rounded

const element = document.getElementById('element-id')
const rect = element.getBoundingClientRect()
element.style.width = roundToEven(rect.width) + 'px'
element.style.height = roundToEven(rect.height) + 'px'

【讨论】:

【参考方案23】:

如果您想要细、规则和粗体文本,您应该选择具有相应字体粗细 的字体。您应该选择粗细为 100 | 的字体400 | 700 示例:如下所示

字体粗细不仅仅是数字。文件应该在服务器或目录中可用。 每个字体粗细都是单独的文件。

如果您在没有资源的情况下强制将常规字体更改为粗体,它会显示模糊。我希望你能明白。

@进口 url('https://fonts.googleapis.com/css2?family=Roboto:wght@100;400;700&display=swap');

【讨论】:

谢谢,这正是我的问题!

以上是关于Chrome 字体显示模糊的主要内容,如果未能解决你的问题,请参考以下文章

chrome 字体发虚模糊是因为啥?

高分屏笔记本第三方chrome浏览器字体模糊怎么办

Chrome 字体模糊解决

谷歌浏览器字体模糊

不透明度低于 1 时带有奇怪阴影(模糊)的字体(仅限 Chrome)

chrome 字体发虚模糊是因为啥