How can I force WebKit to redraw/repaint to propagate style changes?

danorton solution didn't work for me. I had some really weird problems where webkit wouldn't draw some elements at all; where text in inputs wasn't updated until onblur; and changing className would not result in a redraw.

My solution, I accidentally discovered, was to add a empty style element to the body, after the script.

<body>
...
<script>doSomethingThatWebkitWillMessUp();</script>
<style></style>
...

That fixed it. How weird is that? Hope this is helpful for someone.


We recently encountered this and discovered that promoting the affected element to a composite layer with translateZ in CSS fixed the issue without needing extra JavaScript.

.willnotrender { 
   transform: translateZ(0); 
}

As these painting issues show up mostly in Webkit/Blink, and this fix mostly targets Webkit/Blink, it's preferable in some cases. Especially since the accepted answer almost certainly causes a reflow and repaint, not just a repaint.

Webkit and Blink have been working hard on rendering performance, and these kinds of glitches are the unfortunate side effect of optimizations that aim to reduce unnecessary flows and paints. CSS will-change or another succeeding specification will be the future solution, most likely.

There are other ways to achieve a composite layer, but this is the most common.


I found some complicated suggestions and many simple ones that didn’t work, but a comment to one of them by Vasil Dinkov provided a simple solution to force a redraw/repaint that works just fine:

sel.style.display='none';
sel.offsetHeight; // no need to store this anywhere, the reference is enough
sel.style.display='';

I’ll let someone else comment if it works for styles other than “block”.

Thanks, Vasil!