漢堡按鈕(Hamburger menu)經常使用於移動端網站 展開/收起 導航,若是在點擊按鈕時再增長一些過渡動畫則會顯得更加生動有趣。今天咱們就快速實現一個帶有過渡動畫的漢堡按鈕。效果如圖:css
html 結構很簡單,兩個 div
足以:html
<div class="menu"> <div class="hamburger"></div> </div>
div.menu
表明按鈕,div.hamburger
表明按鈕中的線段。可是一個 div
如何顯示 3 條線段?有同窗應該想到了,能夠用 ::before
、::after
僞元素。git
爲了讓代碼更簡潔,選擇使用 Sass 書寫樣式。github
首先咱們須要定義一些變量,減小重複的參數。寫樣式的時候也能夠像寫組件那樣去提煉配置,經過配置去修改、擴展。好比,線段的尺寸、位置均可以經過按鈕尺寸 $menu-size
計算獲得,這樣一旦咱們須要修改按鈕尺寸就只須要修改 $menu-size
這一個參數就好了。sass
變量:動畫
$menu-size: 300px; // 按鈕尺寸 $line-width: $menu-size * 0.66; // 線段寬度 $line-height: $menu-size * 0.1; // 線段高度 $line-spacing: $menu-size * 0.22; // 線段間距 $line-color: #f44336; // 線段顏色
按鈕樣式:網站
常規操做,沒啥好講的...spa
.menu { // 水平、垂直居中 position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); // 寬高 width: $menu-size; height: $menu-size; // 其餘 cursor: pointer; background-color: rgba(255, 255, 255, 0.5); border-radius: 6%; }
線段樣式:3d
.hamburger { // 水平、垂直居中 top: 50%; left: 50%; transform: translate(-50%, -50%); // 線段樣式 &, &::before, &::after { content: ""; position: absolute; width: $line-width; height: $line-height; background: $line-color; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); // 過渡時間 transition: 0.5s; } // 線段1位置 &::before { top: -$line-spacing; } // 線段3位置 &::after { top: $line-spacing; } }
注意點:code
- 使用
transition
設置動畫的過渡時間::before
、::after
僞元素是相對於div.hamburger
進行絕對定位(絕對定位的定義是:相對於最近的非static
定位的祖先元素的進行偏移。而不是 不少同窗印象中的相對於position:relative
的祖先元素進行定位)
激活狀態:
當點擊按鈕後經過 Javascript 給 div.menu
添加 active
的 class,表示按鈕進入激活狀態:
.menu.active { .hamburger { // 隱藏線段2 background-color: transparent; box-shadow: none; // 線段1 旋轉定位 &::before { top: 0; transform: rotate(45deg); } // 線段3 旋轉定位 &::after { top: 0; transform: rotate(135deg); } } }
注意點:
- 隱藏線段 2 不能直接
display:none
或者visibility: hidden
,這樣會致使使用僞元素實現的線段 一、3 都被隱藏,而是經過將背景色設置爲透明實現- 給
::before
,::after
設置top: 0
至關於把線段 一、3 移到按鈕中間,而後再進行旋轉- 設置其餘角度也能夠達到最後變成 x 的效果,好比:
&::after {transform: rotate(-45deg)}
,只不過中間變換的過程會有所區別- 對中間變換過程有疑惑的同窗建議將
transition
時間調長,仔細觀察
最後,監聽按鈕的點擊事件,toggle 激活狀態:
const menu = document.querySelector(".menu"); menu.addEventListener("click", () => { menu.classList.toggle("active"); });
好了,大功告成!
本文 Demo 參考:Codepen Trick by Day (2020-07-07) Transforming Hamburger Menu
天天一個小技巧(Tricks by Day),量變引發質變,但願你和我一塊兒天天多學一點,讓技術有趣一點。全部示例將會彙總到個人 tricks-by-day github 項目中,歡迎你們蒞臨指導 😊