本文來自 「心譚博客」的 《動畫設計·按鈕特效》,更多文章放在了 Github歡迎交流和Starcss
滑箱:html
果凍:css3
脈衝:git
閃光:github
氣泡:dom
由於 button 元素可使用 before/after 僞元素,因此藉助僞元素,能夠實現動態圖中的遮蓋層。性能
爲了不迴流重繪,滑箱的運動方向是垂直方向,因此使用scaleY
屬性。對於動畫的方向,須要藉助transform-origin
改變更畫原點。字體
html:動畫
<button>xin-tan.com</button>
css:spa
button { outline: none; border: none; z-index: 1; position: relative; color: white; background: #40a9ff; padding: 0.5em 1em; } button::before { content: ""; z-index: -1; position: absolute; top: 0; bottom: 0; left: 0; right: 0; background-color: #fa541c; transform-origin: center bottom; transform: scaleY(0); transition: transform 0.4s ease-in-out; } button:hover { cursor: pointer; } button:hover::before { transform-origin: center top; transform: scaleY(1); }
果凍特效能夠分割成 5 個部分,因此沒法簡單經過 transition
來實現,要藉助animation
。而且動畫觸發的時間點是鼠標移入的時候,所以 animation
要在:hvoer
中聲明。
button { z-index: 1; color: white; background: #40a9ff; outline: none; border: none; padding: 0.5em 1em; } button:hover { cursor: pointer; animation: jelly 0.5s; }
下面開始編寫 jelly 動畫的特效。這個動畫能夠分解爲 4 個部分:「初始 => 擠高 => 壓扁 => 回到初始狀態」。擠高 和 壓扁這裏都是經過scale
來實現的,代碼以下:
@keyframes jelly { 0%, 100% { transform: scale(1, 1); } 33% { transform: scale(0.9, 1.1); } 66% { transform: scale(1.1, 0.9); } }
上面的動態已經仿真不錯了,若是將 4 部分變成 5 部分:「初始 => 擠高 => 壓扁 => 擠高 => 回到初始狀態」。視覺上會有一種彈簧的特效,就像手壓果凍後的效果:
@keyframes jelly { 0%, 100% { transform: scale(1, 1); } 25%, 75% { transform: scale(0.9, 1.1); } 50% { transform: scale(1.1, 0.9); } }
首先,仍是去掉 button 的默認樣式。注意設置 button 的z-index
屬性而且讓其生效,要保證其大於 ::before
的 z-index
屬性,防止 dom 元素被僞元素覆蓋。
button { position: relative; z-index: 1; border: none; outline: none; padding: 0.5em 1em; color: white; background-color: #1890ff; } button:hover { cursor: pointer; }
剩下的就是設置僞元素。由於脈衝特效給人的感受是「鏤空」放大。所以,變化對象是 border
屬性。而鏤空的效果,是經過透明背景來實現的。
button::before { content: ""; position: absolute; z-index: -1; top: 0; left: 0; bottom: 0; right: 0; border: 4px solid #1890ff; transform: scale(1); transform-origin: center; }
動畫啓動時間是鼠標移入,border 上變化的是顏色變淡和大小變小,透明度也逐漸變成 0。
button:hover::before { transition: all 0.75s ease-out; border: 1px solid#e6f7ff; transform: scale(1.25); opacity: 0; }
⚠️ transition 和 transform 是放在hover
狀態下的僞元素,目的是讓動畫瞬間回到初始狀態。
實現上依然是藉助僞元素,閃光特效更多注重的是配色,動畫方面實現的核心是利用rotate
來實現「傾斜」的效果,利用translate3d
來實現「閃動」的效果。
button { outline: none; border: none; z-index: 1; position: relative; color: white; background: #262626; padding: 0.5em 1em; overflow: hidden; --shine-width: 1.25em; } button::after { content: ""; z-index: -1; position: absolute; background: #595959; /* 核心代碼:位置一步步調整 */ top: -50%; left: 0%; bottom: -50%; width: 1.25em; transform: translate3d(-200%, 0, 0) rotate(35deg); /* */ } button:hover { cursor: pointer; } button:hover::after { transition: transform 0.5s ease-in-out; transform: translate3d(500%, 0, 0) rotate(35deg); }
⚠️translate3d
除了避免重繪迴流,還能啓用 GPU 加速,性能更高。但以前爲了方便講述,通常使用的是translate
屬性。
首先,仍是禁用 button 元素的默認樣式,而且調整一下配色:
button { outline: none; border: none; cursor: pointer; color: white; position: relative; padding: 0.5em 1em; background-color: #40a9ff; }
因爲 button 的僞元素層級是覆蓋 button 的,因此要設置 z-index
屬性,防止僞元素遮蓋顯示。畢竟只想要背景色的遮蓋,字體不須要遮蓋。在上面的樣式中添加:
button { z-index: 1; overflow: hidden; }
最後處理的是僞元素的變化效果。特效是從中心向四周蔓延,因此應該讓其居中。
對於大小變化,仍是利用scale
屬性。
由於是圓形,因此將border-radius
設置爲 50%便可。
button::before { z-index: -1; content: ""; position: absolute; top: 50%; left: 50%; width: 1em; height: 1em; border-radius: 50%; background-color: #9254de; transform-origin: center; transform: translate3d(-50%, -50%, 0) scale(0, 0); transition: transform 0.45s ease-in-out; } button:hover::before { transform: translate3d(-50%, -50%, 0) scale(15, 15); }
示例代碼中的氣泡特效是從中間向四周擴散,若是想要從左上角向右下角擴散呢?例以下圖所示:
處理過程很簡單,只須要改變一下氣泡的初始位置便可。
button::before { z-index: -1; content: ""; position: absolute; width: 1em; height: 1em; border-radius: 50%; background-color: #9254de; /* 變化位置的代碼 */ top: 0; left: 0; transform-origin: center; transform: scale3d(0, 0, 0); transition: transform 0.45s ease-in-out; /* *********** */ } button:hover::before { transform: scale3d(15, 15, 15); }