CSS Transition在JavaScript修改样式时失效,是否与CSS未即时生效有关?
问题分析:CSS Transition 未生效的原因及解决办法
问题场景
相关代码如下:
CSS 代码
#loading_screen { display: none; z-index: 1; height: 100vh; width: 100vw; opacity: 0; background-color: red; transition: opacity 4s 0s ease; }
HTML & JS 代码
<div id="loading_screen" class="page"> </div> <script> function hide_page() { const loading = document.getElementById('loading_screen'); loading.style.display = 'block'; loading.style.opacity = '1'; } hide_page() </script>
现象:id为loading_screen的div瞬间显示,CSS Transition完全未生效。
疑问:是否存在页面运行时CSS无法立即生效的可能性?
原因解析
这不是CSS无法立即生效,而是浏览器的渲染机制导致的。当你在同一渲染帧里同时修改display和opacity时,浏览器会把这两个样式变更合并成一次渲染操作。因为元素之前处于display: none状态,不在渲染树中,浏览器会直接将其渲染为display: block且opacity: 1的最终状态,跳过了opacity: 0的初始过渡起点,自然触发不了过渡动画。
解决方案
方案一:延迟opacity修改到下一帧
用setTimeout把opacity的调整放到下一帧执行,让浏览器先渲染出display: block且opacity: 0的状态,再触发过渡:
function hide_page() { const loading = document.getElementById('loading_screen'); loading.style.display = 'block'; setTimeout(() => { loading.style.opacity = '1'; }, 0); } hide_page()
方案二:使用requestAnimationFrame
利用浏览器的渲染周期API,同样将opacity修改延迟到下一帧:
function hide_page() { const loading = document.getElementById('loading_screen'); loading.style.display = 'block'; requestAnimationFrame(() => { loading.style.opacity = '1'; }); } hide_page()
方案三:替换display: none为visibility
改用visibility: hidden替代display: none,因为visibility不会从渲染树中移除元素,只是隐藏它,修改opacity时就能正常触发过渡:
修改后的CSS:
#loading_screen { visibility: hidden; opacity: 0; z-index: 1; height: 100vh; width: 100vw; background-color: red; transition: opacity 4s 0s ease; }
修改后的JS:
function hide_page() { const loading = document.getElementById('loading_screen'); loading.style.visibility = 'visible'; loading.style.opacity = '1'; } hide_page()
内容的提问来源于stack exchange,提问作者Giovanni5454
相关产品推荐
相关产品推荐

