Почему этот хак перекраски / перекомпоновки работает?
Иногда нам приходится принудительно перерисовывать / перекомпоновывать браузер для отображения определенных состояний. Например:
window.onload = function () {
setTimeout(function(){
document.getElementById("gradient_text").innerHTML = "bar";
}, 500);
}
#gradient_div {
background: linear-gradient(#000000,#ffffff);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
<div id="gradient_div">
<p id="gradient_text" onload="update">
Foo
</p>
</div>
Элемент Gradient_text отказывается визуально обновлять свой текст до "bar". В некоторых случаях достаточно запустить синхронную перерисовку следующим образом:
...
setTimeout(function(){
var elem = document.getElementById("gradient_text");
// sync force repaint hack
elem.innerHTML="bar";
elem.style.display = 'none';
elem.style.display = 'block';
}, 500);
...
Однако это не работает. По-видимому, это требует асинхронного взлома:
window.onload = function () {
setTimeout(function(){
var elem = document.getElementById("gradient_text");
elem.innerHTML = "bar";
// async force repaint hack
var display = elem.style.display;
elem.style.display = 'none';
setTimeout(function(){
elem.style.display = display
}, 50);
}, 500);
}
#gradient_div {
background: linear-gradient(#000000,#ffffff);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
<div id="gradient_div">
<p id="gradient_text" onload="update">
Foo
</p>
</div>
Что заставляет движок браузера так себя вести? В основном интересует Webkit/Blink.
1 ответ
Из моего комментария следует упростить тестирование из любого браузера:
Я добавил эффект смешивания в режиме смешивания, чтобы Firefox отображал нечто похожее на то, что предполагается в Chrome.
window.onload = document.getElementById("gradient_text").innerHTML = "bar";
/*#gradient_div {
background: linear-gradient(#000000,#ffffff);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
*/
/* UPDATE to show similar text-fill effect in Firefox */
#gradient_div {
background: linear-gradient(#000000,#ffffff);
}
#gradient_text {
background:white;
mix-blend-mode:screen
}
<div id="gradient_div">
<p id="gradient_text">
Foo
</p>
</div>