Post-animación de texto borroso/distorsionado basado en Webkit a través de translate3d


Este problema parece afectar a todos los navegadores basados en WebKit, incluido el iPhone.

Primero algunos antecedentes. El sitio en el que estoy trabajando utiliza una animación 'slider' basada en JavaScript que es básicamente idéntica a esta: http://www.assistly.com/product-tour/#/easy-setup

La única diferencia es que estoy usando -webkit-transform: translate3d para 'alimentar' la animación real. Al usar este método, a diferencia de un método basado en JavaScript, el texto se vuelve borroso una vez que el contenido ha sido animado. Esto es especialmente notable en el iPhone.

Algunas soluciones que vi fueron eliminar un posicionamiento relativo, lo que hice, y agregar una regla para -webkit-font-smoothing: antialiased, lo que también hice. Ninguno de los cambios hizo la más mínima diferencia.

La única forma en que podía hacer que esto funcionara correctamente sin texto borroso era usar JavaScript regular para la animación y omitir el translate3d por completo. Prefiero usar translate3d porque funciona mucho más rápido en WebKit habilitado dispositivos, pero por mi vida no puedo entender por qué está afectando el texto de una manera tan pobre.

Cualquier sugerencia o solución sería muy apreciada.

Author: Volker E., 2011-06-20

16 answers

Como @Robert mencionó anteriormente, a veces agregar fondo ayuda, pero no siempre.

Por lo tanto, para el ejemplo Dmitry agregó que no es lo único que debe hacer: excepto desde el fondo, debe decirle al navegador que use explícitamente el anti-aliasing adecuado, por lo que hay un ejemplo fijo de Dmitry: http://jsfiddle.net/PtDVF/1 /

Necesita agregar estos estilos alrededor (o para los) bloques donde necesita arreglar el suavizado:

background: #FFF; /* Or the actual color of your background/applied image */
-webkit-font-smoothing: subpixel-antialiased;
 18
Author: kizu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-19 20:53:53

Ninguno de estos parece haber funcionado para mí, pero he encontrado una solución un poco sucia que parecía hacer el truco:

top: 49.9%;
left: 49.9%;
-webkit-transform: translate(-50.1%, -50.1%);
transform: translate(-50.1%, -50.1%);
 19
Author: peter waldock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-31 21:46:22

Solucioné este problema añadiendo un estilo translate3d al elemento antes de que ocurriera cualquier animación.

-webkit-transform: translate3d(0,0,0); 
 16
Author: bartburkhardt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-24 07:33:30

Tuve exactamente el mismo problema descrito en el post de Ken Avila: CSS: transform: translate (-50%, -50%) hace que los textos sean borrosos

El problema fue, por supuesto, que utilicé transform: translate(-50%, -50%), lo que hizo que mi contenido centrado se volviera borroso, pero solo en safari en osx.

No es solo el texto lo que se vuelve borroso, sino todo el contenido, incluidas las imágenes. Sigo leyendo: http://keithclark.co.uk/articles/gpu-text-rendering-in-webkit / que el "desenfoque" es debido a que el elemento se representa en un límite no entero.

También descubrí que podía evitar usar transform translate en la parte horizontal de mi centrado de este post: https://coderwall.com/p/quutdq/how-to-really-center-an-html-element-via-css-position-absolute-fixed{[4]-El único inconveniente era que tenía que introducir un envoltorio.

Descubrí que el uso de transform: translateY (-50%) no creó ningún "desenfoque", tal vez porque mi elemento tiene una altura establecida y por lo tanto, no termina renderizando en un límite no entero.

Mi solución terminó así:

.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>
 15
Author: Njaal Gjerde,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:35

Los elementos que está traduciendo deben ser divisibles por dos con números pares.

Es importante que cualquier elemento que estés tratando de desplazar por la mitad sea divisible por dos tanto para su ancho como para su alto. Muy similar a las imágenes responsivas, cuando las cosas se pueden mover en un 50% sin dividir píxeles.

Un div con un ancho de: 503px y una altura de 500px causará desenfoque, no importa de qué manera lo mueva o por cuánto cuando use translateX o Y. Usando transform, utiliza GPU graphics accelerator que debería resultar en bordes muy nítidos y suaves. También podría ser una buena idea establecer box-sizing: border-box; para garantizar que los anchos calculados incluyan relleno y bordes.

Tenga cuidado al usar anchos porcentuales. Si es relativo al tamaño de la pantalla, cualquier otro ancho de píxel de pantalla causará este desenfoque.

 9
Author: factorypolaris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-04 19:27:53

Esta es la mejor solución translateX(calc(-50% + 0.5px))

 4
Author: Neil Taylor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-08 12:58:57

Ninguna de estas respuestas funcionó para mí, pero usando

display: inline-table;

Hizo el truco

 1
Author: user3251328,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-02 01:34:33

Acabo de arreglar esto por un simple truco que no sé la razón. Aquí puedes ver lo diferente.

Originalmente, diseñé el elemento de esta manera:

top: 50%;
left: 50%;
transform: translate(-50%, -50%);

Que conduce al texto borroso... Después de la prueba aleatoria, pongo el estilo en el estilo de clase y fuerzo al procesador CSS a tomar este estilo en lugar del estilo de elemento (como estoy usando componentes de React, los estilos establecidos por React se convertirán en estilo de elemento)

Esto es lo que hice.

.class-name {
    top: 50% !important;
    left: 50% !important;
    transform: translate(-50%, -50%) !important;
}

Realmente quiero saber por qué mover este estilo del estilo de elemento al estilo de clase solucionaría esto. Alguna idea?

 0
Author: PETEroid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-14 01:51:05

Probablemente la solución más fácil:

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

La escala y el zoom se encarga de redondear los valores de píxeles a números completos

 0
Author: Šarūnas Sirotka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-27 09:40:20

Usando zoom solucionado para mí.

Acabo de añadir zoom: 1.04;

 0
Author: Black,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-04 15:52:40

Espero que se trate de centrar el objeto en el centro exacto de la pantalla. El desenfoque ocurre con transform: translate(-50%,-50%);

Así que en lugar de hacer

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

Intenté inyectar estilo en el elemento usando javascript. (Reaccionar.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'
}

Inyectar estilo en el elemento mediante javascript style

Eg.

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>
        );
    }
}
 0
Author: Artaxias,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-24 03:42:00

También tuve el mismo problema cuando usé translateZ, lo resolví usando translateX y translateY juntos y no usando translateZ, así

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

También funciona con fondo transparente

 0
Author: Pushpender,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-30 12:08:14

@kizu Estas respuestas y sugerencias no ayudan. Para su jsfiddle necesita agregar

- webkit-perspectiva-origen: 50% 50%; -webkit-perspectiva: 1400px;

Al elemento padre del elemento en el que desea usar translate3d, de lo contrario traducir el eje z no hace nada. En este caso lo estás aplicando al botón en el que haces clic, creo que quisiste aplicarlo al contenido.

Pero de todos modos, agregar aquellos para activar el cambio del eje z hace que el desenfoque el botón en su ejemplo.

Me encantaría encontrar una solución a esto también, me temo que no hay una.

 -1
Author: Brandon Hutchinson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-13 23:51:58

Para una solución alternativa intente:

-webkit-text-stroke: 0.35px
 -1
Author: ANaimi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-11 07:07:20

Uso will-change en este tipo de problemas, por lo general resuelve problemas de escala o errores de redondeo, como ver una línea blanca de 1px que separa los elementos, por ejemplo.

will-change: transform;

Leer más aquí: https://developer.mozilla.org/en-US/docs/Web/CSS/will-change

 -1
Author: Simon Laroche,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-25 15:27:53

Usando el doctype HTML5 solucioné el problema.

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
 -6
Author: user2049005,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-08 04:37:42