最近在做项目时,发现CSS3中关于动画的技术,自己很少运用在项目中,平时一些列表块的收缩和展开动画效果,几乎都是使用 display 的 none 和 block,或者 visibility 的 hidden 和 visible 来进行控制。因此,在最近的项目中,就开始深入研究CSS3关于动画的技术,并且运用到了项目中,下面是关于列表块的收缩&展开动画。
简单的一个效果图
实现思路
大体上我们将列表块分割成 标题块 和 内容块
(1)标题块: 展示标题和一个带有收缩&展开动画效果的图标
①图标部分,我们可以使用伪类来绘画出箭头,并且使用 transform 的旋转属性 rotate 进行图标的方向控制和其动画效果。
②动画控制,通常点击标题部分,列表则收缩&展开,因此点击标题时,要对class进行控制。
(2)内容块:内容块展示内容,且该块承载了主要的动画效果——列表的收缩&展开
①动画效果:该块的动画,我们的思路是整个块的高度收起来,里面的内容也向左边隐藏,因此需要控制高度和动画的隐藏,所以使用 max-height 进行高度控制和 transition(设置动画时间)、transform 的属性 translate 来进行内容的隐藏
完整代码如下:
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title></title>
5 <style type="text/css">
6 .block_wrap {
7 width: 500px;
8 margin: 0 auto;
9 border: 1px solid #e3e3e3;
10 border-radius: 10px;
11 }
12 .chapter_wrap {
13 background: white;
14 text-align: left;
15 border-radius: 8px;
16 color: #333333;
17 margin-bottom: 15px;
18 font-size: 14px;
19 overflow: hidden;
20 }
21 .title_item_wrap {
22 padding: 10px 10px 10px 0;
23 margin: 0 10px 0 10px;
24 border-bottom: none;
25 display: flex;
26 align-items: center;
27 }
28 /*使用伪类进行图标绘画*/
29 .title_item_wrap::after {
30 content: '';
31 width: 10px;
32 height: 10px;
33 border-top: 2px solid #999999;
34 border-right: 2px solid #999999;
35 transform: rotate(-45deg);
36 display: inline-block;
37 transition: 0.3s;
38 float: right;
39 margin-top: 10px;
40 }
41 /*使用类acitve类控制图标的旋转和展开时标题的下边界*/
42 .active {
43 border-bottom: 1px solid #F0F0F0;
44 }
45 .active::after{
46 transform: rotate(135deg);
47 margin-top: 5px;
48 }
49 .chapter_title {
50 font-size: 16px;
51 padding: 0;
52 margin: 0;
53 width: calc(100% - 30px);
54 }
55 .node_wrap {
56 overflow: hidden;
57 overflow-y: scroll;
58 transition: 0.3s;
59 }
60 .node_wrap p {
61 padding: 0 20px 5px 20px;
62 margin: 10px 0;
63 border-bottom: 1px solid #e3e3e3
64 }
65 /*隐藏内容块的滑动条*/
66 .node_wrap::-webkit-scrollbar {
67 display: none;
68 }
69 /*控制内容块隐藏 隐藏时,整块向左边平移200%的宽度,并且将最大高度设置为0,否则页面会留有空白*/
70 .node_wrap_hide {
71 transform: translate(-200%, 0);
72 max-height: 0;
73 }
74 /*控制内容块显示,显示时,整块向右边复原,并且将最大高度设置为300px,里面的内容即会将块撑开*/
75 .node_wrap_show {
76 transform: translate(0, 0);
77 max-height: 300px;
78 }
79 </style>
80 </head>
81 <body>
82 <div class="block_wrap">
83 <div id="block_wrap" class="title_item_wrap active">
84 <p class="chapter_title">章节名称</p>
85 </div>
86 <div id="list_wrap" class="node_wrap node_wrap_show">
87 <p>节名称一</p>
88 <p>节名称二</p>
89 <p>节名称三</p>
90 <p>节名称四</p>
91 <p>节名称五</p>
92 <p>节名称六</p>
93 <p>节名称七</p>
94 <p>节名称八</p>
95 <p>节名称九</p>
96 <p>节名称十</p>
97 </div>
98 </div>
99 </body>
100 <script type="text/javascript">
101 // 获取标题元素
102 var block_wrap = document.getElementById('block_wrap')
103
104 //给标题元素添加点击事件,通过点击控制class的添加&去除达成动画效果
105 block_wrap.onclick = function() {
106 // 获取标题元素className集合
107 let classArray = this.className.split(/\s+/)
108
109 // 获取内容块元素
110 let list_wrap = document.getElementById('list_wrap')
111
112 // 判断标题元素是否有类active,如若存在,则说明列表展开,这时点击则是隐藏内容块,否则显示内容块
113 if (classArray.includes('active')) {
114 // 隐藏内容块
115 block_wrap.classList.remove('active')
116 list_wrap.classList.remove('node_wrap_show')
117 list_wrap.classList.add('node_wrap_hide')
118 console.log(this.className.split(/\s+/))
119 return
120 } else {
121 // 显示内容块
122 block_wrap.classList.add('active')
123 list_wrap.classList.add('node_wrap_show')
124 list_wrap.classList.remove('node_wrap_hide')
125 return
126 }
127 }
128 </script>
129 </html>
以上代码直接复制到HTML文件保存后即可看到效果。此动画效果适应移动端,PC端会有点瑕疵,稍微处理即可。