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 the equivalent of a smack upside the head. - We reset 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 that will not otherwise alter the appearance of the element:
element.style.webkitTransform = "scale(1)";
Or in CSS:
.quickfix { transform: translateZ(0); }
- If the element is absolutely positioned: adding a
z-index
value 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.
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.