最近在做項目時,發現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端會有點瑕疵,稍微處理即可。