为何.container::after元素在动画过程中会改变位置?
问题原因与解决方案
为什么伪元素会跟着父元素动画?
这是CSS规则导致的:任何设置了transform且值不为none的元素,会自动成为其所有绝对定位后代的包含块——哪怕这个元素本身没设置position: relative/absolute。
你的.container::after原本是绝对定位,相对于main(因为main设置了position: relative)定位。但当鼠标悬停时,.container被加上了transform: rotate(360deg),此时.container就变成了伪元素的新包含块,伪元素自然会跟着父元素一起旋转。
你之前给.container加position: relative没用,是因为这只会让伪元素默认相对于.container定位,反而更绑定了父子关系,和你想要的效果背道而驰。
怎么避免伪元素跟着动?
核心思路是切断伪元素和设置了transform的父元素的包含块关系,下面给两种可行方案:
方案1:把伪元素转移到main上
直接让伪元素属于main,这样它的定位上下文始终是main,完全不受.container的transform影响:
/* 替换原来的main .container::after */ main::after { position: absolute; top: 200px; left: 100px; background-color: white; color: gold; content: "after div"; } /* 原动画逻辑保留 */ main:hover .container { transform: rotate(360deg); color: purple; transition: all 2s; }
方案2:给父元素加一层包裹,把transform移到包裹上
如果需要伪元素仍属于.container但不跟着旋转,可以给.container套一个外层容器,把transform应用在容器上,让.container本身不触发包含块变化:
修改后的HTML:
<main> <div class="container-wrap"> <div class="container">I am a container</div> </div> </main>
修改后的CSS:
/* 动画应用在包裹层 */ main:hover .container-wrap { transform: rotate(360deg); transition: all 2s; } /* .container只保留颜色变化 */ main:hover .container { color: purple; } /* 伪元素仍属于.container,定位上下文还是main */ main .container::after { position: absolute; top: 200px; left: 100px; background-color: white; color: gold; content: "after div"; }
两种方案都能实现伪元素不随.container旋转的效果,你可以根据实际需求选择。
内容的提问来源于stack exchange,提问作者Hiwa
相关产品推荐
相关产品推荐

