display:none状态下CSS @keyframes文本动画失效问题求助
问题:点击复制图标时通知动画未生效
我受教授指派实现点击复制图标时显示通知的功能,尝试使用@keyframes结合opacity实现动画,但未达到预期效果,相关代码如下:
关键帧设置
.copyNotification { display: none; position: absolute; right: 0; } .copyNotification.show { display: block; animation: show 0.5s backwards; } @keyframes show { 0% { transform: translateY(-100%); opacity: 0; } 100% { transform: translateY(0%); opacity: 1; } }
完整代码片段
JavaScript
const copyBtn = document.querySelector("#copyBtn"); const copyNotification = document.querySelector("#copyNotification"); copyBtn.addEventListener("click", function (e) { e.preventDefault(); copyNotification.classList.add("show"); });
CSS
:root { /* Font Size */ --ff--primary: "Chivo", sans-serif; /* Font Weight */ --fw--bold: 400; --fw--very-bold: 600; /* Colors */ --clr--purple: hsl(250, 95%, 74%); --clr--white: hsl(0, 0%, 100%); } /* 1. Use a more-intuitive box-sizing model. */ *, *::before, *::after { box-sizing: border-box; } /* 2. Remove default margin */ * { margin: 0; } /* Typographic tweaks! 3. Add accessible line-height 4. Improve text rendering */ body { line-height: 1.5; -webkit-font-smoothing: antialiased; } /* 5. Improve media defaults */ img, picture, video, canvas, svg { display: block; max-width: 100%; } /* 6. Remove built-in form typography styles */ input, button, textarea, select { font: inherit; } /* 7. Avoid text overflows */ p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; } /* 8. Create a root stacking context */ #root, #__next { isolation: isolate; } body { background-color: var(--clr--purple); min-height: 100vh; display: grid; place-items: center; font-family: var(--ff--primary); font-size: var(--fw--bold); } .passwordForm { display: grid; height: 200px; max-width: 450px; background-color: var(--clr--white); padding: 1.5rem; border-radius: 1rem; h1 { text-align: center; } .divider { border-top: 1.5px solid var(--clr--purple); margin-bottom: 1rem; margin-inline: -1.5rem; } form { display: grid; gap: 2rem; .copyNotification { display: none; position: absolute; right: 0; } .copyNotification.show { display: block; animation: show 0.5s backwards; } @keyframes show { 0% { transform: translateY(0%); opacity: 0; } 100% { transform: translateY(-100%); opacity: 1; } } .passwordDisplay { position: relative; width: 100%; .copyBtn { position: absolute; font-size: 2rem; top: 0; right: 1rem; i { cursor: pointer; color: var(--clr--purple); } i:hover { opacity: 0.7; } i:active { opacity: 0.5; } } .passwordValue { border: 2px solid #937efc; width: 100%; padding: 0.7rem 1rem; } .passwordValue:focus { border-color: hsl(250, 95%, 74%, 0.6); -webkit-box-shadow: -2px 4px 15px -6px rgba(147, 126, 252, 1); -moz-box-shadow: -2px 4px 15px -6px rgba(147, 126, 252, 1); box-shadow: -2px 4px 15px -6px rgba(147, 126, 252, 1); outline: 0 none; } } } }
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="style.css" class="css" /> <link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" /> <link href="https://fonts.googleapis.com/css2?family=Chivo:wght@400;600&display=swap" rel="stylesheet" /> <title>Password Generator JS</title> </head> <body> <main class="passwordForm"> <h1>Password Generator</h1> <div class="divider"></div> <form action="#"> <div class="passwordDisplay"> <input type="text" disabled="disabled" class="passwordValue" id="passwordValue" placeholder="Password" /> <div class="copyBtn" id="copyBtn"> <i class="fa-regular fa-copy"></i> </div> <p class="copyNotification" id="copyNotification">Copied</p> </div> </form> </main> <script src="app.js"></script> </body> </html>
问题分析与修复方案
核心问题
display: none无法触发动画:元素从display: none切换到display: block时,浏览器不会计算过渡/动画,因为元素瞬间进入文档流,没有中间状态。- 动画关键帧逻辑混乱:原代码中关键帧的
transform方向前后不一致,且未给通知设置初始定位,导致动画效果异常。 - 通知未自动隐藏:点击后通知会一直停留在页面上,没有自动消失的交互逻辑。
修改后的代码
CSS 调整
/* 替换原copyNotification相关样式 */ .copyNotification { position: absolute; right: 1rem; top: -2.5rem; /* 定位到复制按钮上方 */ opacity: 0; visibility: hidden; transform: translateY(20px); /* 初始向下偏移 */ transition: all 0.3s ease; background-color: var(--clr--purple); color: var(--clr--white); padding: 0.3rem 0.8rem; border-radius: 0.3rem; } .copyNotification.show { opacity: 1; visibility: visible; transform: translateY(0); }
JavaScript 调整
const copyBtn = document.querySelector("#copyBtn"); const copyNotification = document.querySelector("#copyNotification"); copyBtn.addEventListener("click", function (e) { e.preventDefault(); // 先移除类再添加,避免重复点击无动画 copyNotification.classList.remove("show"); void copyNotification.offsetWidth; // 触发重绘 copyNotification.classList.add("show"); // 2秒后自动隐藏通知 setTimeout(() => { copyNotification.classList.remove("show"); }, 2000); });
修复说明
- 用
opacity和visibility替代display控制显示隐藏,保留元素在文档流中的位置,确保过渡动画生效。 - 给通知添加背景色和内边距,提升视觉辨识度,同时设置合理的定位,避免遮挡其他元素。
- 添加定时器实现通知自动隐藏,同时处理重复点击的动画触发问题(通过移除类+触发重绘,确保每次点击都能播放动画)。
内容的提问来源于stack exchange,提问作者DailyFun
相关产品推荐
相关产品推荐

