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. 神经网络优化篇:详解局部最优的问题(The problem of local optima)

    局部最优的问题 在深度学习研究早期,人们总是担心优化算法会困在极差的局部最优,不过随着深度学习理论不断发展,对局部最优的理解也发生了改变.向展示一下现在怎么看待局部最优以及深度学习中的优化问题. 这是 ...

  2. 百度网盘(百度云)SVIP超级会员共享账号每日更新(2023.12.20)

    一.百度网盘SVIP超级会员共享账号 可能很多人不懂这个共享账号是什么意思,小编在这里给大家做一下解答. 我们多知道百度网盘很大的用处就是类似U盘,不同的人把文件上传到百度网盘,别人可以直接下载,避免 ...

  3. MySQL高可用九种方案

    有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top 首发博客地址 参考视频 MMM 方案(单主) MySQL 高可用方案之 MM ...

  4. [转帖]nginx源码层面探究request_time、upstream_response_time、upstream_connect_time与upstream_header_time指标具体含义与区别

    https://www.cnblogs.com/AcAc-t/p/nginx_request_time_upstream_respone_time_analysis.html 背景概述 最近计划着重分 ...

  5. [转帖]5. Tikv安装部署

    5. Tikv安装部署 5.1. 概述 TiDB 是 PingCAP 公司自主设计.研发的开源分布式关系型数据库,是一款同时支持在线事务处理与在线分析处理 (Hybrid Transactiona ...

  6. [转帖]45个处理字符串的Python方法

    https://baijiahao.baidu.com/s?id=1738413163267646541&wfr=spider&for=pc   一.题目解析 先来看一个题目: 判断用 ...

  7. [转帖]Linux中./configure、make、make install命令详解

    简单来说,make 是编译,make install 是安装.   总结:linux编译安装中configure.make和make install各自的作用  • ./configure是用来检测你 ...

  8. [转帖]016 Linux 卧槽,看懂进程信息也不难嘛?top、ps

    016 Linux 卧槽,看懂进程信息也不难嘛?top.pshttps://my.oschina.net/u/3113381/blog/5455267 1 扒开看看 top 命令参数详情 Linux ...

  9. [转帖]一本正经的八卦一下CPU的自主可控 之二

    https://zhuanlan.zhihu.com/p/62399200 一本正经的八卦一下CPU的自主可控 之二 上回书说到CPU自主可控第一个层面的指令集问题.这回聊一聊接下来的设计问题. 第二 ...

  10. 【如何提高IT运维效率】深度解读京东云基于NLP的运维日志异常检测AIOps落地实践

    作者:京东科技  张宪波.张静.李东江 基于NLP技术对运维日志聚类,从日志角度快速发现线上业务问题 日志在IT行业中被广泛使用,日志的异常检测对于识别系统的运行状态至关重要.解决这一问题的传统方法需 ...