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 小时前
Vue 生产环境打包:SourceMap、压缩、混淆、加密全解 + 最佳实践
前端·javascript·vue.js
巴博尔3 小时前
UNIAPP中NVUE页面 动画
android·前端·javascript·ios·uni-app
她说人狗殊途5 小时前
基于 vue-cli 创建
前端·javascript·vue.js
AZaLEan__6 小时前
前端移动端适配与 Bootstrap
前端·bootstrap·html
大家的林语冰6 小时前
Deno 2.8 正式发布,再次超越 Bun,史上最大的次版本升级诞生!
前端·javascript·node.js
渣渣xiong6 小时前
从零开始:前端转型AI agent直到就业第五十七天-第五十八天
前端·人工智能·python
AI周红伟7 小时前
周红伟:长鑫科技(CXMT)财务全景分析
前端·chrome·科技
excel7 小时前
JS 正则在多次 test() 时为什么会出现 lastIndex 缓存问题?
前端
IT_陈寒7 小时前
为什么 Java 的 Optional 让我调试到深夜?
前端·人工智能·后端
米丘8 小时前
React 19.x 的 lazy 与 Suspense
前端·javascript·react.js