2

I have a transition implemented with this code:

h1 {
position: absolute;
z-index: 2;
line-height: 1;
font-size: 8em;
transition: all 10s;
pointer-events: none;
font-weight: 600;
width: 800px;
font-family: 'Crimson Text', serif;
margin: 0;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);

&.top-left {
  top: 0%;
  left: 0%;
  transform: translate(0%, 0%);
  width: 300px;
  font-size: 3em;
}

And it doesn't work as needed on Safari. I tried to do scale animation instead but it has the same effect. Any idea how to fix that?

Chrome: http://www.giphy.com/gifs/VzkdenswxQA29t6sNH

Safari: http://www.giphy.com/gifs/QW9RGCPQoqkFeRWLu7

Bryce Howitson
  • 7,339
  • 18
  • 40
Ilya Libin
  • 1,576
  • 2
  • 17
  • 39
  • Does it do the same thing with a fixed size div without any text content? Eg: make a square with a solid color bg. And does it happen if you use a pixel size on the text? – Bryce Howitson Jun 07 '19 at 20:14
  • 1
    Also can you create a working example that replicates what you're seeing? I have some ideas, but it's not worth tossing out "did you try this or that?" without being able to try it myself. Also, can you do it without changing the width? That causes text to reflow on each frame. – Bryce Howitson Jun 07 '19 at 20:19
  • I don't have it on fiddle currently. But I have it here online https://capture7.com/preview/showfields-pos-rx1gBCRAcciupQ @BryceHowitson – Ilya Libin Jun 07 '19 at 20:26

1 Answers1

2

The problem is that you're causing properties to transition that force the browser to compute layout changes (width & font-size).

The reason that's a problem has to do with the order browsers calculate what's rendered on the screen. It's usually in this order:

  1. Styles (what to apply - CSS specificity)
  2. Layout (width/height, font-size, margin/padding, display)
  3. Paint (color, border, background, shadows, etc)
  4. Composite (position, scale, opacity, etc)

Animating #3 & #4 are pretty efficient. The other stuff not so much so it's best to try avoiding those.


There's a couple of things you can do to improve performance across the board

First force the computer to use its GPU for rendering. The easiest way to do this is with a 3d transform.

h1 {
transform: translate3d(-50%, -50%, 0);
}

&.top-left {
  transform: translate(0, 0, 0);
}

Next, let's tell the browser we're going to mess with this element so it can get ready to be more efficient.

h1 {
 will-change: transform;
}

Finally, we need to rethink the transform itself to avoid changing layout. Let's do that by removing the font-size and width properties and replacing with a transform: scale And in an ideal world, we'd remove transition between top/left position but its probably ok here.

h1 {
   position: absolute;
   z-index: 2;
   line-height: 1;
   font-size: 8em;
   transition: all 10s;
   pointer-events: none;
   font-weight: 600;
   /* width: 800px; */
   font-family: 'Crimson Text', serif;
   margin: 0;
   top: 50%;
   left: 50%;
   transform: translate(-50%, -50%, 0) scale(1);
   will-change: transform;
}
&.top-left {
  top: 0%;
  left: 0%;
  transform: translate(0, 0, 0) scale(0.25);
  /* width: 300px; */
  /* font-size: 3em; */
}
Bryce Howitson
  • 7,339
  • 18
  • 40