CSS 显示隐藏动画(动画失效问题)

就像这个动画一样的效果,div 先是隐藏的,点击按钮后显示并且有动画效果,隐藏的时候同样。

js 复制代码
  <button class="btn" id="btn">点击</button>
  <div class="box" id="box"></div>

  <script>
    const btn = document.getElementById('btn')
    const box = document.getElementById('box')
    let show = false
    btn.onclick = function () {
      if (show) {
        box.classList.add('fadeout')
        box.classList.remove('fadein')
      } else {
        box.classList.add('fadein')
        box.classList.remove('fadeout')
        
      }
      show = !show;
    }
  </script>

在css中,可以利用 animation 属性和 @keyframes 规则来实现元素显示与隐藏的动画效果,通过 @keyframes 规则,您能够创建动画。

js 复制代码
  <style>
    .box {
      width: 50px;
      height: 50px;
      background: red;
      display: none;
    }
    .fadeout {
      animation: fadeout 1s;
    }
    .fadein {
      display: block;
      animation: fadein 1s;
      
    }
	/* 移出动画 */
    @keyframes fadeout {
      0% {
        opacity: 1;
        display: block;
      }
      100% {
        opacity: 0;
        display: block;
      }
    }
    /* 进入动画 */
    @keyframes fadein {
      0% {
        opacity: 0;
      }
      100% {
        opacity: 1;
      }
    }
  </style>

在 CSS 中,display: none; 和 display: block; 是两种完全不同的属性,它们控制元素的显示方式。display: none; 会使元素不可见且不占据空间,而 display: block; 会使元素以块级元素的方式显示,并占据相应的空间。

因此,你不能直接在 display: none; 和 display: block; 之间应用动画效果,因为这两个属性之间的切换是瞬间完成的,没有中间状态可以应用动画。

这样就引发了一个问题:如果我们要设置类似淡入淡出的效果怎么办?就是让元素在消失/出现的同时产生动画怎么办?不要使用 transition 动画,而是用 animation 动画,并且在进入动画的时候设置元素的显示,然后在出动画帧定义的地方设置元素的显示。

js 复制代码
    .fadein {
      /* 注意这行代码 */
      display: block; 
      animation: fadein 1s;
      
    }
	/* 移出动画 */
    @keyframes fadeout {
      0% {
        opacity: 1;
        /* 注意这行代码 */
        display: block;
      }
      100% {
        opacity: 0;
        /* 注意这行代码 */
        display: block;
      }
    }

此时我们已知掌握了动画的基本操作,接下来演示一个基本的弹窗动画。

js 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      background: red;
      display: none;
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate3d(-50%, -50%, 0);
      padding: 12px;
      border-radius: 8px;
    }
    .fadeout {
      animation: fadeout 0.3s;
    }
    .fadein {
      display: block;
      animation: fadein 0.3s;
      
    }

    /* 移出动画 */
    @keyframes fadeout {
      0% {
        opacity: 1;
        display: block;
      }
      100% {
        opacity: 0;
        display: block;
      }
    }
    /* 进入动画 */
    @keyframes fadein {
      0% {
        transform: translate3d(-50%, -50%, 0) scale(0.9);
      }
      50% {
        transform: translate3d(-50%, -50%, 0) scale(1.1);
      }
      100% {
        transform: translate3d(-50%, -50%, 0) scale(1);
      }
    }
  </style>
</head>
<body>
  <button class="btn" id="btn">按钮</button>
  <div class="box" id="box">您确定提交数据吗?</div>

  <script>
    const btn = document.getElementById('btn')
    const box = document.getElementById('box')
    let show = false
    btn.onclick = function () {
      if (show) {
        box.classList.add('fadeout')
        box.classList.remove('fadein')
      } else {
        box.classList.add('fadein')
        box.classList.remove('fadeout')
        
      }
      show = !show;
    }
  </script>
</body>
</html>
相关推荐
~无忧花开~3 分钟前
CSS学习笔记(五):CSS媒体查询入门指南
开发语言·前端·css·学习·媒体
程序猿小D10 分钟前
【完整源码+数据集+部署教程】【零售和消费品&存货】价格标签检测系统源码&数据集全套:改进yolo11-RFAConv
前端·yolo·计算机视觉·目标跟踪·数据集·yolo11·价格标签检测系统源码
吴鹰飞侠18 分钟前
AJAX的学习
前端·学习·ajax
JNU freshman24 分钟前
vue 技巧与易错
前端·javascript·vue.js
落一落,掉一掉32 分钟前
第十二周 waf绕过和前端加密绕过
前端
Asort32 分钟前
JavaScript设计模式(十六)——迭代器模式:优雅遍历数据的艺术
前端·javascript·设计模式
Coffeeee41 分钟前
Labubu很难买?那是因为还没有用Compose来画一个
前端·kotlin·android jetpack
我是日安41 分钟前
从零到一打造 Vue3 响应式系统 Day 28 - shallowRef、shallowReactive
前端·javascript·vue.js
开源之眼43 分钟前
深入理解 JavaScript 报错:TypeError: undefined is not a function
前端·javascript
LRH43 分钟前
时间切片 + 双工作循环 + 优先级模型:React 的并发任务管理策略
前端·react.js