60

此问题似乎会影响所有基于 WebKit 的浏览器,包括 iPhone。

首先是一些背景。我正在开发的网站使用基于 JavaScript 的“滑块”动画。

我正在-webkit-transform: translate3d用来为实际动画“供电”。使用此方法时,与基于 JavaScript 的方法相反,一旦内容被动画化,文本就会变得非常模糊。这在 iPhone 上尤其明显。

我看到的一些解决方法是删除相对定位,我这样做了,并添加了一个规则-webkit-font-smoothing: antialiased,我也这样做了。这两种变化都没有丝毫不同。

我可以在没有模糊文本的情况下使其正常工作的唯一translate3d方法是使用常规 JavaScript 制作动画并完全绕过它。我更喜欢使用它,translate3d因为它在支持 WebKit 的设备上执行更快,但对于我的生活,我无法弄清楚为什么它会以如此糟糕的方式影响文本。

任何建议或解决方案将不胜感激。

4

19 回答 19

24

这些似乎都不适合我,但我发现了一个有点脏的解决方案,似乎可以解决问题:

top: 49.9%;
left: 49.9%;
-webkit-transform: translate(-50.1%, -50.1%);
transform: translate(-50.1%, -50.1%);
于 2016-03-31T21:46:22.923 回答
21

正如上面提到的@Robert,有时添加背景会有所帮助,但并非总是如此。

因此,对于 Dmitry 添加的示例,这不是您必须做的唯一事情:除了从后台,您必须告诉浏览器显式使用正确的抗锯齿,因此,有一个固定的 Dmitry 示例:http: //jsfiddle.net /PtDVF/1/

您需要在需要修复抗锯齿的块周围(或为)添加这些样式:

background: #FFF; /* Or the actual color of your background/applied image */
-webkit-font-smoothing: subpixel-antialiased;
于 2011-09-19T20:53:53.523 回答
20

我遇到了 Ken Avila 的帖子中描述的完全相同的问题:CSS: transform: translate(-50%, -50%) makes text blurry

问题当然是我使用了 transform: translate(-50%, -50%) 这使我居中的内容变得模糊,但仅在 osx 上的 safari 中。

不仅文本变得模糊,而且包括图像在内的整个内容都变得模糊。我继续阅读:http ://keithclark.co.uk/articles/gpu-text-rendering-in-webkit/ “模糊”是由于元素呈现在非整数边界上。

我还发现我可以避免在这篇文章的居中水平部分使用转换翻译:https ://coderwall.com/p/quutdq/how-to-really-center-an-html-element-via-css -position-absolute-fixed -唯一的缺点是我必须引入一个包装器。

我发现使用 transform: translateY(-50%) 并没有产生任何“模糊”,可能是因为我的元素有一个设定的高度,因此最终不会在非整数边界上渲染。

因此,我的解决方案最终是这样的:

.wrapper {
  position: fixed;
  left: 50%;
  top: 50%;
}
.centered {
  position: relative;
  left: -50%;
  -webkit-transform: translateY(-50%);
  -ms-transform: translateY(-50%);
  transform: translateY(-50%);
}
<div class="wrapper">
  <div class="centered">
    Content
  </div>
</div>

于 2015-09-01T10:53:31.887 回答
18

您正在翻译的元素必须能被偶数的 2 整除。

重要的是,无论您试图移动一半的元素的宽度和高度都可以被 2 整除,这一点很重要。与响应式图像非常相似,当物体可以移动 50% 而不分割像素时。

宽度为:503px,高度为 500px 的 div 会导致模糊,无论您以何种方式移动它或使用 translateX 或 Y 时移动多少。使用变换,它利用 GPU 图形加速器,结果应该非常清晰、流畅边缘。设置 box-sizing: border-box; 也可能是一个好主意。确保计算的宽度包括填充和边框。

使用百分比宽度时要小心。如果它与屏幕尺寸相关,那么其他屏幕像素宽度都会导致这种模糊。

于 2017-01-04T05:35:22.473 回答
16

我通过translate3d在任何动画发生之前向元素添加样式来解决此问题。

-webkit-transform: translate3d(0,0,0); 
于 2012-09-12T07:31:10.313 回答
7

这是最好的解决方案 translateX(calc(-50% + 0.5px))

于 2017-09-08T12:58:57.407 回答
3

可能是最简单的解决方案:

transform: translate(-50%, -50%) scale(2); 
zoom:.5;

Scale-and-zoom 负责将像素值四舍五入为整数

于 2017-07-27T09:40:20.367 回答
2

Neil Taylor 的解决方案是最好的,但仍然可以改进:

transform: translateX(-50%) translateX(.5px)

这种方式有2个优点:

  • 它适用于像 IE11 这样的蹩脚浏览器(不支持 calc inside translate)
  • 它只在解析时计算,而不是在浏览器每次评估时计算。
于 2019-11-06T11:14:56.203 回答
1

这些答案都不适合我,但使用

display: inline-table;

成功了

于 2016-09-02T01:34:33.787 回答
0

将应用了 transform translate 属性的容器中的任何元素的垂直边距(margin-top 或 margin-bottom)或高度仅减少 1 个像素。

于 2019-06-24T09:56:08.690 回答
0

我希望这是关于将对象居中到屏幕的确切中心。变换发生模糊: translate(-50%,-50%);

所以而不是做

position: absolute;
margin:0;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);

我尝试使用 javascript 将样式注入元素。(反应.js)

const node = ReactDOM.findDOMNode(this);
var width = node.offsetWidth;
var height = node.offsetHeight;
var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;

style={
    left : (windowWidth/2) - (this.state.width/2) + 'px',
    right:  (windowWidth/2) - (this.state.width/2) + 'px',
    top: (windowHeight/2) - (this.state.height/2) + 'px',
    bottom: (windowHeight/2) - (this.state.height/2) + 'px'
}

通过javascript样式将样式注入元素

例如。

export default class Dialog extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            width: '0px',
            height: '0px'
        };
    }

    setWidthhandHeight(node){
        if (this.state.width !== node.offsetWidth) {
            this.setState({
                width: node.offsetWidth,
                height: node.offsetHeight
            });
        }
    }

    componentDidMount() {
        this.setWidthhandHeight(node);
    }

    render() {
        const windowWidth = window.innerWidth;
        const windowHeight = window.innerHeight;
        return (
            <dialog className={this.props.className + " dialog"}
                    style={{
                        left : (windowWidth/2) - (this.state.width/2) + 'px',
                        right:  (windowWidth/2) - (this.state.width/2) + 'px',
                        top: (windowHeight/2) - (this.state.height/2) + 'px',
                        bottom: (windowHeight/2) - (this.state.height/2) + 'px'
                    }}>
                {this.props.title ? (
                    <header><span>{this.props.title}</span></header>
                    )
                    : null
                }
                {this.props.children}
            </dialog>
        );
    }
}
于 2018-07-24T03:42:00.297 回答
0

如果百分比用于动画,如果我们还考虑它的性能,它仍然可以接受,但是当您不translate用于动画时,它会有所不同,因为文本总是会模糊。

使用百分比时,可能会有小数0.5px这就是文本模糊的原因。在我的实验中,使用translate(0.5px, 0.5px)会使文本非常模糊,所以你应该避免0.3px <=> 0.7px0.2px and 0.8px仍然可以接受的情况下使用小数。

我的建议是使用 JavaScript 并将百分比转换为圆角像素来为元素设置动画,如果translate用于定位元素,则使用像素而不是百分比。

另一种选择是使用leftand使用百分比top设置初始位置,然后使用像素作为目标位置并仅使用transform: translate()transformtransition-property: transform;

于 2020-03-16T05:16:22.850 回答
0

使用zoom为我解决了它。

我刚刚添加zoom: 1.04;

于 2018-06-04T15:47:20.867 回答
0

将 Chrome 的缩放比例重置为 100% 对我有用。

于 2019-11-12T12:02:31.583 回答
-1

对于替代解决方案,请尝试:

-webkit-text-stroke: 0.35px
于 2012-11-11T07:07:20.327 回答
-1

在我的案例中找到的解决方案是设置height第一个子元素的值

于 2018-12-12T13:27:31.060 回答
-2

@kizu 这些答案和建议无济于事。对于您的 jsfiddle,您需要添加

-webkit-perspective-origin:50% 50%;-webkit-透视:1400px;

到要使用 translate3d 的元素的父元素,否则平移 z 轴实际上不会做任何事情。在这种情况下,您将其应用于单击的按钮,我认为您打算将其应用于内容。

但无论如何,添加这些以激活 z 轴更改会导致示例中的按钮模糊。

我也很想找到解决方案,我担心没有。

于 2012-03-13T23:51:58.820 回答
-2

我使用will-change这些类型的问题,它通常解决缩放问题或舍入错误,例如看到一个 1px 白线分隔元素。

will-change: transform;

在这里阅读更多: https ://developer.mozilla.org/en-US/docs/Web/CSS/will-change

于 2018-01-25T15:27:53.543 回答
-8

使用 HTML5 doctype 为我解决了这个问题。

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
于 2013-08-08T04:37:42.000 回答