
本文旨在解决网页中通知面板上滑动画不流畅的问题,通过分析现有代码的不足,详细介绍了三种优化方案:利用 `position: sticky` 实现无抖动吸顶效果、使用 css transitions 实现同步动画、以及运用 web animations api 精确控制动画过程。最终帮助开发者实现更平滑、更专业的用户体验。
在网页设计中,一个流畅的动画效果能够显著提升用户体验。本文将针对一个常见的需求:当用户点击“Got it”按钮后,页面顶部的通知面板(Panel)平滑上滑消失,同时页面主体(Main Page)向上移动填补空白区域。我们将分析现有实现方案的不足,并提供三种优化方法,确保动画的流畅性和视觉效果。 ### 问题分析 原方案中,通知面板和页面主体的动画效果分别独立控制,导致动画不同步,产生“白色间隙”或视觉抖动。具体问题如下: 1. **动画距离不同步**:通知面板上滑的距离 (`translateY(-1000px)`) 与页面主体上移的距离 (`top: 0`) 不一致。 2. **动画时间不同步**:通知面板的动画时间为 1 秒,而页面主体的动画时间为 0.2 秒。 3. **`position: fixed` 的潜在问题**:在某些屏幕尺寸下,使用 `position: fixed` 可能会导致通知面板与页面主体内容重叠,或者在动画过程中产生视觉抖动。 ### 解决方案 为了解决上述问题,我们提供了三种优化方案:使用 `position: sticky`、使用 CSS Transitions 和使用 Web Animations API。 #### 方案一:利用 `position: sticky` `position: sticky` 是一种混合了 `position: relative` 和 `position: fixed` 特性的定位方式。当元素在视口中时,表现为 `relative`,当滚动到特定位置时,表现为 `fixed`。 **优势**: * 实现吸顶效果,无需 JavaScript 控制。 * 避免了 `position: fixed` 可能引起的布局问题和视觉抖动。 * 代码简洁,易于维护。 **实现步骤**: 1. **CSS 修改**: * 将 `.panel` 的 `position` 设置为 `sticky`,`top` 设置为 `0`。 * 添加 `transition` 属性,控制 `margin-bottom` 和 `transform` 的动画效果。 ```css .panel{ z-index: 1; position: sticky; top: 0; transition: margin-bottom 1s, transform 1s; }JavaScript 修改:
const panel = document.getElementById('panel');
const page = document.getElementById('main-page');
function closePanel(){
const {bottom} = panel.getBoundingClientRect();
panel.style.marginBottom = 0 + "px";
panel.addEventListener("transitionend", () => panel.replaceWith());
// marginBottom shrinks the element;
// translateY() slides it out.
setTimeout(() => {
panel.style.marginBottom = `${-bottom}px`;
panel.style.transform = `translateY(${-bottom}px)`;
}, 0);
}完整代码:
<div class="panel" id="panel">
<div class="notif-panel" id="notifPanel">
<div class="panel-content">
<p class="panel-text">By accessing and using this website, you acknowledge that you have read and
<span class="brCust" id="brCust"></span>understand our
<a class="cookie" href="#">Cookie Policy</a>,
<a class="privacy" href="#">Cookie Policy</a>, and our
<a class="tos" href="#">Terms of Service</a>.
</p>
<button class="panel-button" onclick="closePanel()">Got it</button>
</div>
</div>
</div>
<div class="main-page" id="main-page">
<section class="hero" id="hero">
@@##@@
<div class="hero-content">
<p class="name">Hello! I'm Dylan Anderton</p>
<h2 class="slogan">Consult, Design, and Develop Websites</h2>
<p class="contact-text">Have something great in mind? Feel free to contact me.<br> I'll help you to make it happen.</p>
<button class="contact-button">LET'S MAKE CONTACT</button>
</div>
</section>
</div>.panel{
z-index: 1;
position: sticky;
top: 0;
transition:
margin-bottom 1s,
transform 1s;
}
.hero {
position: relative;
}
*{
margin:0;
padding:0;
}
html {--smokeGrey:#eee}
.notif-panel{
display:grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
grid-template-areas: "panel-content";
}
.panel-content{
display:flex;
justify-content:center;
align-items:center;
background-color:var(--smokeGrey);
}
.panel-text{
display:inline;
}
.cookie, .privacy, .tos{
text-decoration:none;
}
.panel-button{
display:inline;
padding: 10px 16px;
background-color: #007bc1;
color: white;
border: none;
border-radius: 2px;
}
.panel-button:hover{
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
@media(max-width:675px){
.notif-panel{
height: 10%;
}
.panel-content{
padding: 0 5px;
}
.panel-text{
padding-right: 15px;
}
.panel-button{
font-size: 17px;
}
}
@media(max-width:605px){
.notif-panel{
height: 15%;
}
.panel-content{
align-items: left;
display: block;
padding: 10px;
font-size: 18px;
}
.panel-text{
padding-bottom: 10px;
display: block;
}
.panel-button{
font-size: 17px;
}
}
.main-page{
width: 100%;
}
.hero{
display: flex;
justify-content: center;
align-items: center;
background-image: linear-gradient(rgba(0,74,117,.52),rgba(0,74,117,.52)), url('assets/work-desk__dustin-lee.jpg');
height: 600px;
}
.logo{
height: 50px;
width: 50px;
position: absolute;
left: 30px;
top: 25px;
}
.hero-content{
margin:0;
text-align: center;
color: white;
}
.name{
font-size: 30px;
}
.contact-text{
margin-top: 8px;
padding-bottom: 25px;
}
.contact-button{
font-weight: bold;
color: white;
background-color: transparent;
border: white 2px solid;
padding: 12px 15px;
border-radius: 2px;
}
.contact-button:hover{
color: var(--blue);
background-color: white;
}CSS Transitions 允许我们平滑地改变 CSS 属性的值。
实现步骤:
CSS 修改:
/* I had to move position:fixed to this top-level element */
.panel{
z-index: 1;
position: fixed;
}JavaScript 修改:
const panel = document.getElementById('panel');
const page = document.getElementById('main-page');
function closePanel(){
const rectPanel = panel.getBoundingClientRect();
panel.style.top = 0;
page.style.top = rectPanel.bottom + "px";
panel.style.transition = "top 1s ease-in-out";
page.style.transition = "top 1s ease-in-out";
// Don't forget to remove it from the DOM
panel.addEventListener("transitionend", () => panel.replaceWith());
setTimeout(() => {
panel.style.top = -rectPanel.bottom + "px";
page.style.top = 0;
}, 0);
}完整代码:
<div class="panel" id="panel">
<div class="notif-panel" id="notifPanel">
<div class="panel-content">
<p class="panel-text">By accessing and using this website, you acknowledge that you have read and
<span class="brCust" id="brCust"></span>understand our
<a class="cookie" href="#">Cookie Policy</a>,
<a class="privacy" href="#">Privacy Policy</a>, and our
<a class="tos" href="#">Terms of Service</a>.
</p>
<button class="panel-button" onclick="closePanel()">Got it</button>
</div>
</div>
</div>
<div class="main-page" id="main-page">
<section class="hero" id="hero">
@@##@@
<div class="hero-content">
<p class="name">Hello! I'm Dylan Anderton</p>
<h2 class="slogan">Consult, Design, and Develop Websites</h2>
<p class="contact-text">Have something great in mind? Feel free to contact me.<br> I'll help you to make it happen.</p>
<button class="contact-button">LET'S MAKE CONTACT</button>
</div>
</section>
</div>/* I had to move position:fixed to this top-level element */
.panel{
z-index: 1;
position: fixed;
}
*{
margin:0;
padding:0;
}
html {--smokeGrey:#eee}
.notif-panel{
display:grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
grid-template-areas: "panel-content";
}
.panel-content{
display:flex;
justify-content:center;
align-items:center;
background-color:var(--smokeGrey);
}
.panel-text{
display:inline;
}
.cookie, .privacy, .tos{
text-decoration:none;
}
.panel-button{
display:inline;
padding: 10px 16px;
background-color: #007bc1;
color: white;
border: none;
border-radius: 2px;
}
.panel-button:hover{
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
@media(max-width:675px){
.notif-panel{
height: 10%;
}
.panel-content{
padding: 0 5px;
}
.panel-text{
padding-right: 15px;
}
.panel-button{
font-size: 17px;
}
}
@media(max-width:605px){
.notif-panel{
height: 15%;
}
.panel-content{
align-items: left;
display: block;
padding: 10px;
font-size: 18px;
}
.panel-text{
padding-bottom: 10px;
display: block;
}
.panel-button{
font-size: 17px;
}
}
.main-page{
position: absolute;
width: 100%;
}
.hero{
display: flex;
justify-content: center;
align-items: center;
background-image: linear-gradient(rgba(0,74,117,.52),rgba(0,74,117,.52)), url('assets/work-desk__dustin-lee.jpg');
height: 600px;
}
.logo{
height: 50px;
width: 50px;
position: absolute;
left: 30px;
top: 25px;
}
.hero-content{
margin:0;
text-align: center;
color: white;
}
.name{
font-size: 30px;
}
.contact-text{
margin-top: 8px;
padding-bottom: 25px;
}
.contact-button{
font-weight: bold;
color: white;
background-color: transparent;
border: white 2px solid;
padding: 12px 15px;
border-radius: 2px;
}
.contact-button:hover{
color: var(--blue);
background-color: white;
}Web Animations API 提供了更强大的动画控制能力,可以精确地控制动画的每一个细节。
实现步骤:
CSS 修改:
/* I had to move position:fixed to this top-level element */
.panel{
z-index: 1;
position: fixed;
}JavaScript 修改:
const panel = document.getElementById('panel');
const page = document.getElementById('main-page');
function closePanel(){
const {bottom} = panel.getBoundingClientRect();
const duration = 1000; // ms
panel.animate(
{ top: [0, `${-bottom}px`] },
{ duration }
).finished.then(() => {
panel.replaceWith(); // Don't forget to remove element from DOM!
});
page.animate(
{ top: [`${bottom}px`, 0] },
{ duration }
);
}完整代码:
<div class="panel" id="panel">
<div class="notif-panel" id="notifPanel">
<div class="panel-content">
<p class="panel-text">By accessing and using this website, you acknowledge that you have read and
<span class="brCust" id="brCust"></span>understand our
<a class="cookie" href="#">Cookie Policy</a>,
<a class="privacy" href="#">Privacy Policy</a>, and our
<a class="tos" href="#">Terms of Service</a>.
</p>
<button class="panel-button" onclick="closePanel()">Got it</button>
</div>
</div>
</div>
<div class="main-page" id="main-page">
<section class="hero" id="hero">
@@##@@
<div class="hero-content">
<p class="name">Hello! I'm Dylan Anderton</p>
<h2 class="slogan">Consult, Design, and Develop Websites</h2>
<p class="contact-text">Have something great in mind? Feel free to contact me.<br> I'll help you to make it happen.</p>
<button class="contact-button">LET'S MAKE CONTACT</button>
</div>
</section>
</div>/* I had to move position:fixed to this top-level element */
.panel{
z-index: 1;
position: fixed;
}
*{
margin:0;
padding:0;
}
html {--smokeGrey:#eee}
.notif-panel{
display:grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
grid-template-areas: "panel-content";
}
.panel-content{
display:flex;
justify-content:center;
align-items:center;
background-color:var(--smokeGrey);
}
.panel-text{
display:inline;
}
.cookie, .privacy, .tos{
text-decoration:none;
}
.panel-button{
display:inline;
padding: 10px 16px;
background-color: #007bc1;
color: white;
border: none;
border-radius: 2px;
}
.panel-button:hover{
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
@media(max-width:675px){
.notif-panel{
height: 10%;
}
.panel-content{
padding: 0 5px;
}
.panel-text{
padding-right: 15px;
}
.panel-button{
font-size: 17px;
}
}
@media(max-width:605px){
.notif-panel{
height: 15%;
}
.panel-content{
align-items: left;
display: block;
padding: 10px;
font-size: 18px;
}
.panel-text{
padding-bottom: 10px;
display: block;
}
.panel-button{
font-size: 17px;
}
}
.main-page{
position: absolute;
width: 100%;
}
.hero{
display: flex;
justify-content: center;
align-items: center;
background-image: linear-gradient(rgba(0,74,117,.52),rgba(0,74,117,.52)), url('assets/work-desk__dustin-lee.jpg');
height: 600px;
}
.logo{
height: 50px;
width: 50px;
position: absolute;
left: 30px;
top: 25px;
}
.hero-content{
margin:0;
text-align: center;
color: white;
}
.name{
font-size: 30px;
}
.contact-text{
margin-top: 8px;
padding-bottom: 25px;
}
.contact-button{
font-weight: bold;
color: white;
background-color: transparent;
border: white 2px solid;
padding: 12px 15px;
border-radius: 2px;
}
.contact-button:hover{
color: var(--blue);
background-color: white;
}本文针对通知面板上滑动画不流畅的问题,提供了三种优化方案。其中,使用 position: sticky 的方案代码最简洁,且避免了视觉抖动,是推荐的选择。使用 CSS Transitions 和 Web Animations API 的方案,虽然代码相对复杂,但提供了更强大的动画控制能力。开发者可以根据实际需求选择合适的方案。
注意事项:



以上就是实现平滑的上滑动画效果:优化通知面板的显示与隐藏的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号