0

0

实现平滑滑出动画效果:优化页面元素过渡

心靈之曲

心靈之曲

发布时间:2025-10-19 11:52:23

|

363人浏览过

|

来源于php中文网

原创

 实现平滑滑出动画效果:优化页面元素过渡

本文旨在解决在网页中实现平滑滑出动画时可能出现的白色间隙问题。通过分析问题根源,提供了三种解决方案:利用`position: sticky`属性、使用css transitions以及web animations api。重点在于确保动画同步,避免视觉上的不流畅感,从而提升用户体验。

在网页开发中,经常需要实现一些动画效果来提升用户体验。其中,滑出动画是一种常见的交互方式,例如在页面顶部显示一个通知面板,用户点击“知道了”按钮后,面板滑出并消失,同时页面主体向上移动以填充面板留下的空间。然而,在实现这种动画时,有时会遇到动画不够平滑,出现白色间隙的问题。本文将深入探讨这个问题,并提供多种解决方案。 ### 问题分析 造成动画不平滑的原因通常在于: 1. **元素定位方式不当:** 使用`position: fixed`虽然能使元素固定在屏幕某个位置,但在不同屏幕尺寸下可能导致元素重叠或出现间隙。 2. **动画不同步:** 如果滑出面板和页面主体向上移动的动画距离和时间不一致,就会出现视觉上的不协调,导致动画不流畅。 为了解决这些问题,我们需要采用更合适的定位方式和更精确的动画控制。 ### 解决方案一:利用 `position: sticky` `position: sticky` 是一种结合了 `position: relative` 和 `position: fixed` 特性的定位方式。当元素在视口中时,它的行为类似于 `position: relative`;当元素滚动到特定位置时,它的行为则类似于 `position: fixed`。 **优点:** * 无需JavaScript计算位置,简化代码。 * 避免了`position: fixed`可能导致的元素重叠问题。 * 动画效果自然流畅,减少视觉抖动。 **代码示例:** ```html

By accessing and using this website, you acknowledge that you have read and understand our Cookie Policy, Privacy Policy, and our Terms of Service.

Hello! I'm Dylan Anderton

Consult, Design, and Develop Websites

Have something great in mind? Feel free to contact me.
I'll help you to make it happen.

.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;
}
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);
}

注意事项:

  • position: sticky 需要指定 top、right、bottom 或 left 属性,才能生效。
  • 部分旧版本浏览器可能不支持 position: sticky,需要进行兼容性处理。

解决方案二:使用 CSS Transitions

CSS Transitions 允许您在 CSS 属性值发生变化时,平滑地过渡到新的值。通过精确控制滑出面板和页面主体的 top 属性,可以实现同步的动画效果。

代码示例:

By accessing and using this website, you acknowledge that you have read and understand our Cookie Policy, Privacy Policy, and our Terms of Service.

@@##@@

Hello! I'm Dylan Anderton

Consult, Design, and Develop Websites

Have something great in mind? Feel free to contact me.
I'll help you to make it happen.

/* 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;
}
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);
}

代码解释:

  1. 获取面板高度: 使用 panel.getBoundingClientRect() 获取面板的尺寸和位置信息。
  2. 设置初始位置: 将面板的 top 属性设置为 0,并将页面主体的 top 属性设置为面板的高度,使其紧贴面板下方。
  3. 添加过渡效果: 为面板和页面主体添加 transition 属性,指定过渡的属性(top)、持续时间(1s)和缓动函数(ease-in-out)。
  4. 触发动画: 使用 setTimeout 延迟一段时间后,将面板的 top 属性设置为 -rectPanel.bottom + "px",使其向上滑出,同时将页面主体的 top 属性设置为 0,使其向上移动填充面板留下的空间。
  5. 移除DOM元素: 在动画结束后,将面板从DOM中移除,避免影响页面布局。

注意事项:

  • 确保面板和页面主体的过渡时间和缓动函数一致,以实现同步的动画效果。
  • 使用 setTimeout 延迟触发动画,可以避免浏览器优化导致的动画卡顿。

解决方案三:使用 Web Animations API

Web Animations API 提供了更强大的动画控制能力,允许您使用 JavaScript 创建复杂的动画效果。

DALL·E 2
DALL·E 2

OpenAI基于GPT-3模型开发的AI绘图生成工具,可以根据自然语言的描述创建逼真的图像和艺术。

下载

代码示例:

By accessing and using this website, you acknowledge that you have read and understand our Cookie Policy, Privacy Policy, and our Terms of Service.

@@##@@

Hello! I'm Dylan Anderton

Consult, Design, and Develop Websites

Have something great in mind? Feel free to contact me.
I'll help you to make it happen.

/* 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;
}
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 }
  );
}

代码解释:

  1. 获取面板高度: 与 CSS Transitions 方案相同,首先获取面板的高度。
  2. 创建动画: 使用 panel.animate() 和 page.animate() 创建动画对象,指定动画的属性(top)、起始值和结束值,以及动画的持续时间。
  3. 移除DOM元素: 使用 finished.then() 监听面板动画的结束,并在动画结束后将面板从DOM中移除。

注意事项:

  • Web Animations API 提供了更多的动画控制选项,例如缓动函数、循环次数、延迟等。
  • 可以使用 keyframe format 指定属性值在不同时间点的变化。

总结

本文介绍了三种解决滑出动画不平滑问题的方法:使用 position: sticky、CSS Transitions 和 Web Animations API。每种方法都有其优缺点,您可以根据实际需求选择最合适的方案。

  • position: sticky 最简单易用,但可能存在兼容性问题。
  • CSS Transitions 适用于简单的动画效果,代码简洁易懂。
  • Web Animations API 提供了更强大的动画控制能力,适用于复杂的动画效果。

无论选择哪种方案,都需要确保动画同步,避免视觉上的不协调,从而提升用户体验。此外,还应注意代码的兼容性,确保在不同浏览器下都能正常运行。

					

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

782

2023.07.31

python中的format是什么意思
python中的format是什么意思

python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

434

2024.06.27

cookie
cookie

Cookie 是一种在用户计算机上存储小型文本文件的技术,用于在用户与网站进行交互时收集和存储有关用户的信息。当用户访问一个网站时,网站会将一个包含特定信息的 Cookie 文件发送到用户的浏览器,浏览器会将该 Cookie 存储在用户的计算机上。之后,当用户再次访问该网站时,浏览器会向服务器发送 Cookie,服务器可以根据 Cookie 中的信息来识别用户、跟踪用户行为等。

6427

2023.06.30

document.cookie获取不到怎么解决
document.cookie获取不到怎么解决

document.cookie获取不到的解决办法:1、浏览器的隐私设置;2、Same-origin policy;3、HTTPOnly Cookie;4、JavaScript代码错误;5、Cookie不存在或过期等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

347

2023.11.23

阻止所有cookie什么意思
阻止所有cookie什么意思

阻止所有cookie意味着在浏览器中禁止接受和存储网站发送的cookie。阻止所有cookie可能会影响许多网站的使用体验,因为许多网站使用cookie来提供个性化服务、存储用户信息或跟踪用户行为。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

411

2024.02.23

cookie与session的区别
cookie与session的区别

本专题整合了cookie与session的区别和使用方法等相关内容,阅读专题下面的文章了解更详细的内容。

92

2025.08.19

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

469

2024.01.03

python中class的含义
python中class的含义

本专题整合了python中class的相关内容,阅读专题下面的文章了解更多详细内容。

13

2025.12.06

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

158

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.8万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.1万人学习

CSS教程
CSS教程

共754课时 | 24.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号