Under certain conditions, Webkit will not repaint the browser window to reflect DOM additions or changes. This is a known bug: in the case of Wednesday’s article on making an automatic image checkerboard with SVG and JavaScript, switching from rectangular to circular clipping areas in Chrome will produce an effect that looks like Figure 1:
To address this in the CodePen version, I’ve added four lines to the end of the script:
var bridge = document.querySelector("#clipit img");
bridge.style.display="none";
bridge.offsetHeight;
bridge.style.display="block";
This finds the image, quickly hides it, calculates its current height, and then sets it back to display: block. For all purposes this happens instantaneously, so there is no visual “flicker” in the browser. There are just two things to note:
- We don’t have to store
offsetHeight; referencing it is enough to give Webkit a reminder that the element should be redrawn. - We redraw the image to which the SVG is applied, not the SVG itself.
Other Solutions
This is not an absolute suggestion, just the best one I’ve found. However, it may force both a reflow and repaint, making Webkit work overtime. There are some other solutions that may be more effective in certain cases:
- Adding an empty
<style></style>tag after the script; either dynamically with JavaScript or writing it directly into the code of the page. Adding a transform or something else that will not otherwise alter the appearance of the element:
element.style.webkitTransform = "scale(1)";Or in CSS:
.quickfix { transform: translateZ(0); }Similar techniques involve adding and removing an invisible outline:
.quickfix { outline: 0px; }If the element is absolutely positioned: adding a
z-indexvalue to the element can force a repaint:element.style.zIndex = "2";
This fix is not needed in every case, and I hope it will be unnecessary in the future, but right now when you need it, you really need it.
Pro CSS3 Animation, Apress, 2013
Massive Head Canon
The New Defaults
CSSslidy