CSS实现展开动画

展开收起效果是比较常见的一种交互方式,通常的做法是控制display属性值在none和其它值之间切换,虽说功能可以实现,但是效果略显生硬,所以会有这样的需求——希望元素展开收起能具有平滑的效果。

实现

max-height

首先想到的是通过height0auto之间切换,但是结果可能并不会是我们所预期的那样,原因是我们将要展开的元素内容是动态的,即高度值不确定,因此height使用的值是默认的auto,从0pxauto是无法计算的,因此无法形成过渡或动画效果。

据此我们可以使用max-height,将max-height0过渡到一个能够大于完全显示内部元素的值,展开后的max-height值,只需要设定为保证比展开内容高度大的值即可,在max-height值比height值大的情况下,元素仍会默认采用自身的高度值即auto,如此一来一个高度不定的元素展开收起动画效果就实现了。

请注意这种方式实现还是有限制的,使用CSS进行过渡动画的时候依旧是通过计算0到设定的max-height高度值进行计算的,在实际应用中如果max-height值太大,在元素收起的时候将会产生延迟的效果,这是因为在收起时,max-height从设定的特别大的值,到元素自身高度值的变化过程将占用较多时间,此时画面表现则会产生延迟的效果。因此建议将max-height值设置为足够安全的最小值,这样在收起时即使有略微延迟,也会因为时间很短,难以被用户感知,将不会影响体验。

<!DOCTYPE html>
<html>
<head>
<title>展开动画</title>
<style type="text/css">
.page{
width: 200px;
padding: 10px 20px;
border: 1px solid #eee;
}
.container {
overflow: hidden;
}
.container > .options{
transition: all .5s;
max-height: 0;
}
.container > .unfold{
max-height: 150px;
}
.container > .btn{
color: #4C98F7;
cursor: pointer;
text-decoration: underline;
}
</style>
</head>
<body>
<div class="page">
<div class="container">
<div class="btn" onclick="operate(this)" unfold="1">展开</div>
<div class="options">
<div class="option">选项1</div>
<div class="option">选项2</div>
<div class="option">选项3</div>
<div class="option">选项4</div>
<div class="option">选项5</div>
<div class="option">选项6</div>
<div class="option">选项7</div>
</div>
</div>
</div>
</body>
<script type="text/javascript">
function operate(btn){
const optionsNode = document.querySelector(".container > .options");
const unfold = btn.getAttribute("unfold");
if(unfold && unfold==="1"){
btn.innerText = "收缩";
optionsNode.classList.add("unfold");
}else{
btn.innerText = "展开";
optionsNode.classList.remove("unfold");
}
btn.setAttribute("unfold", unfold === "0" ? "1" : "0");
}
</script>
</html>

height

使用max-height必定有一定的局限性,那么不如我们在DOM加载完成后就取得元素的实际高度并保存,之后直接利用这个真实高度与0进行动画过渡即可,因为浏览器的渲染顺序,在解析JavaScript时会阻塞DOM的渲染,所以在获取元素实际高度再设置高度为0的过程中一般不会出现闪烁的情况,如果实在担心因为获取高度之后再将高度设置为0可能会有一个闪烁的过程,那么我们可以取得元素父节点后调用cloneNode(true)方法或者innerHTML方法取得字符串再innerHTML到一个新创建的节点,目的就是将其拷贝,之后将其使用绝对定位等放置到屏幕外即将其设置到屏幕能够显示的外部区域,注意此时要设置bodyoverflow: hidden;,之后利用getComputedStyle取得实际高度,然后再将其移出DOM结构,此时有了实际高度就可以进行动画过渡了,下面简单的实现一下在DOM加载时便取得实际高度进行动画实现。

<!DOCTYPE html>
<html>
<head>
<title>展开动画</title>
<style type="text/css">
.page{
width: 200px;
padding: 10px 20px;
border: 1px solid #eee;
}
.container {
overflow: hidden;
}
.container > .options{
transition: all .5s;
}
.container > .btn{
color: #4C98F7;
cursor: pointer;
text-decoration: underline;
}
</style>
</head>
<body>
<div class="page">
<div class="container">
<div class="btn" onclick="operate(this)" unfold="1">展开</div>
<div class="options">
<div class="option">选项1</div>
<div class="option">选项2</div>
<div class="option">选项3</div>
<div class="option">选项4</div>
<div class="option">选项5</div>
<div class="option">选项6</div>
<div class="option">选项7</div>
</div>
</div>
</div>
</body>
<script type="text/javascript">
(function init(win, doc){
const optionsNode = document.querySelector(".container > .options");
optionsNode.setAttribute("real-height", win.getComputedStyle(optionsNode).height);
optionsNode.style.height = "0px";
})(window, document); function operate(btn){
const optionsNode = document.querySelector(".container > .options");
const unfold = btn.getAttribute("unfold");
const realHeight = optionsNode.getAttribute("real-height");
if(unfold && unfold==="1"){
btn.innerText = "收缩";
optionsNode.style.height = realHeight;
}else{
btn.innerText = "展开";
optionsNode.style.height = "0px";
}
btn.setAttribute("unfold", unfold === "0" ? "1" : "0");
}
</script>
</html>

translateY

还有一种常用实现动画的方式,即首先将外层元素没有动画过渡的形式直接展开,再将选项加入动画缓慢下落,通常利用transform: translateY();去实现这个缓慢下降的动画,在微信的WEUI小程序组件库的首页就是采用这种实现方式。

<!DOCTYPE html>
<html>
<head>
<title>展开动画</title>
<style type="text/css">
.page{
width: 200px;
padding: 10px 20px;
border: 1px solid #eee;
}
.container, .options-container {
overflow: hidden;
}
.options-container{
height: 0;
}
.container .options{
transition: all .5s;
transform: translateY(-100%);
}
.container .unfold{
transform: translateY(0);
}
.container > .btn{
color: #4C98F7;
cursor: pointer;
text-decoration: underline;
}
</style>
</head>
<body>
<div class="page">
<div class="container">
<div class="btn" onclick="operate(this)" unfold="1">展开</div>
<div class="options-container">
<div class="options">
<div class="option">选项1</div>
<div class="option">选项2</div>
<div class="option">选项3</div>
<div class="option">选项4</div>
<div class="option">选项5</div>
<div class="option">选项6</div>
<div class="option">选项7</div>
</div>
</div>
</div>
</div>
</body>
<script type="text/javascript">
function operate(btn){
const optionsNode = document.querySelector(".container .options");
const optionsContainer = document.querySelector(".options-container");
const unfold = btn.getAttribute("unfold");
if(unfold && unfold==="1"){
btn.innerText = "收缩";
optionsNode.classList.add("unfold");
optionsContainer.style.height = "auto";
}else{
btn.innerText = "展开";
optionsNode.classList.remove("unfold");
optionsContainer.style.height = "0px";
}
btn.setAttribute("unfold", unfold === "0" ? "1" : "0");
}
</script>
</html>

每日一题

https://github.com/WindrunnerMax/EveryDay

参考

http://www.111com.net/wy/192615.htm
https://zhuanlan.zhihu.com/p/52582555
https://cloud.tencent.com/developer/article/1499033

CSS实现展开动画的更多相关文章

  1. jQuery鼠标悬停3d菜单展开动画

    效果体验:http://hovertree.com/texiao/jquery/93/ 竖直的主菜单贴着页面左侧,当光标移入菜单项时,以3D动画的方式弹出对应的二级菜单.采用jQuery和CSS3实现 ...

  2. 为网格布局图片打造的超炫 CSS 加载动画

    今天,我想与大家分享一些专门为网格布局的图像制作的很酷的 CSS 加载动画效果.您可以把这些效果用在你的作品集,博客或任何你想要的网页中.设置很简单.我们使用了下面这些工具库来实现这个效果: Norm ...

  3. 一个纯CSS DIV天气动画图标【转扒的】

    <p> </p> <style><!-- /* SUNNY */ .sunny { -webkit-animation: sunny 15s linear i ...

  4. WPF(C#) 矩阵拖动、矩阵动画、边缘展开动画处理。

    最近在研发新的项目,遇到了一个桌面模式下的难点--展开动画.之前动画这方面没做过,也许很多人开始做的时候也会遇到相关问题,因此我把几个重点及实际效果图总结展示出来: 我的开发环境是在VS2017下进行 ...

  5. CSS图片翻转动画技术详解

    因为不断有人问我,现在我补充一下:IE是支持这种技术的!尽管会很麻烦.需要做的是旋转front和back元素,而不是旋转整个容器元素.如果你使用的是最新版的IE,可以忽略这一节.IE10+是支持的,I ...

  6. JavaScript是如何工作的: CSS 和 JS 动画底层原理及如何优化它们的性能

    摘要: 理解浏览器渲染. 原文:JavaScript是如何工作的: CSS 和 JS 动画底层原理及如何优化它们的性能 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 这是专门探索 J ...

  7. 简单的CSS圆形缩放动画

    简单的CSS圆形缩放动画 话不多说鼠标移动上去,看效果吧,效果预览 代码如下: <!DOCTYPE html> <html> <head> <title> ...

  8. 网页DIV+CSS布局和动画美化全程实例 (陈益材) 随书光盘

    网站的建站技术近几年得到迅速的发展,网页的布局与特效动画技术层出不穷,网站建设已经从简单的技术支持时代衍变到现在的视觉美化时代.但如何使设计的网页高人一筹,达到让人过目不忘的境界,如何追求以最简单的特 ...

  9. animate.css引入实现动画效果

    最近在网上看到很多代码都通过引入animate.css来实现动画效果,后来我便使用这种方法来尝试着写了个小案例,结果真的很好用,比我们通常情况下使用css或js实现动画效果好得多,便在此做个总结. 第 ...

  10. How Javascript works (Javascript工作原理) (十三) CSS 和 JS 动画底层原理及如何优化其性能

    个人总结:读完这篇文章需要20分钟. 这是 JavaScript 工作原理的第十三章. 概述 正如你所知,动画在创建令人叹服的网络应用中扮演着一个关键角色.由于用户越来越注重用户体验,商户开始意识到完 ...

随机推荐

  1. Springboot开发的应用为什么这么占用内存

    Springboot开发的应用为什么这么占用内存 Java的原罪 Java 程序员比 c或者是c++程序员相比轻松了很多. 不要管理繁杂的内存申请与释放,也不用担心因为忘记释放内存导致很严重的内存泄漏 ...

  2. [转帖]oracle数据库中RMAN备份格式化format解释

    格式化解释: 使用格式串 更改格式命令: RMAN> configure channel device type disk format ' E:\app\Administrator\db_ba ...

  3. [转帖]TiKV & TiFlash 加速复杂业务查询丨TiFlash 应用实践

    返回全部 边城元元案例实践2022-08-02 复杂业务查询对于传统的关系型数据库来说是一种考验,而通过 TiKV 行存与 TiFlash 的列存结合使用就能很好地应对.本文根据 TUG 用户边城元元 ...

  4. [转帖]CentOS-7-x86_64-Everything-2009 rpm包列表(CentOS7.9)

    CentOS-7-x86_64-Everything-2009 rpm包列表(CentOS7.9) 共10073个文件 复制389-ds-base-1.3.10.2-6.el7.x86_64.rpm ...

  5. [转帖]docker-compose完全清除

    https://www.cnblogs.com/gelandesprung/p/12112420.html#:~:text=docker-compose%E5%AE%8C%E5%85%A8%E6%B8 ...

  6. [转帖]QPS 最高提升 91% | 腾讯云 TKE 基于 Cilium eBPF 提升 k8s Service 性能

    https://my.oschina.net/cncf/blog/5121393   朱瑜坚,腾讯云后台工程师,主要负责腾讯云 TKE 容器网络的构建和相关网络组件的设计.开发和维护工作.张浩,腾讯云 ...

  7. [转帖]Nginx动静分离详解以及配置

    https://developer.aliyun.com/article/885602?spm=a2c6h.24874632.expert-profile.314.7c46cfe9h5DxWK 简介: ...

  8. 自建邮箱服务器 EwoMail 发送邮件的办法

    总结来源: http://doc.ewomail.com/docs/ewomail/changguipeizhi 1. 首先这个机器不能安装dovecot等软件,不然安装脚本会失败. 2. 下载安装文 ...

  9. C# 求两个时间的差值

    商品保质期 //dateStart:系统时间: dateEnd :物品到期日期 DateTime dateStart = DateTime.Now.Date;//2021/7/8 DateTime d ...

  10. 【Java】ArrayList线程不安全的坑

    问题复现: 使用Java的steam().paralleStream(),foreach()方法向ArrayList添加数据,导致ArrayList中出现空值,代码如下: public static ...