在各種UI組件庫大行其道的今天,大家已經很少自己用CSS去實現一些效果了,久而久之CSS的水平也越來越退步,所以有空還是得練練。今天給大家分享8種炫酷按鈕的CSS實現。
1. 3D按鈕1
現在的主流是扁平化的設計,擬物化的設計比較少見了,所以我們僅從技術角度去分析如何實現這個3D按鈕(文中只列出各種實現的關鍵代碼,完整代碼請參考CodePen)。
該按鈕的立體效果主要由按鈕多出的左、下兩個側面襯托出來,我們可以使用box-shadow
模擬出這兩個側面:
HTML:
<button class="button-3d-1">3D Button 1</button>
CSS:
.button-3d-1{
position: relative;
background: orangered;
border: none;
color: white;
padding: 15px 24px;
font-size: 1.4rem;
outline: none;
box-shadow: -6px 6px 0 hsl(16, 100%, 30%);
}
效果:
加了box-shadow
之後整體形狀有點像了,但是立方體的左上和右下確缺了一塊。通過觀察我們發現,缺的這兩塊是三角形的,所以如果我們能構造兩個三角形補到這兩個角上就行了。用CSS畫三角形對大家來說應該是基本操作了,如果還有同學不知道,下面的動畫很好的解釋了原理(代碼參考 Triangle):
我們使用::before
和::after
僞元素來分別繪製左上、右下的兩個三角形,並通過絕對定位將它們固定到兩個角落:
CSS:
.button-3d-1::before {
content: "";
display: block;
width: 0;
height: 0;
position: absolute;
top: 0;
left: -6px;
border: 6px solid transparent;
border-right: 6px solid hsl(16, 100%, 30%);
border-left-width: 0px;
}
.button-3d-1::after {
content: "";
display: block;
width: 0;
height: 0;
position: absolute;
bottom: -6px;
right: 0;
border: 6px solid transparent;
border-top: 6px solid hsl(16, 100%, 30%);
border-bottom-width: 0px;
}
接下來,我們需要實現點擊時按鈕被按下的效果,思路是點擊時將按鈕正面向左下角移動,同時減少box-shadow
的偏移量以達到按鈕底部固定不動的效果:
CSS:
.button-3d-1:active {
background: hsl(16, 100%, 40%);
top: 3px;
left: -3px;
box-shadow: -3px 3px 0 hsl(16, 100%, 30%);
}
最後,我們需要重新計算左上、右下兩個三角形的尺寸和位置,以適應按下後上下缺口的變小:
CSS:
.button-3d-1:active::before {
border: 3px solid transparent;
border-right: 3px solid hsl(16, 100%, 30%);
border-left-width: 0px;
left: -3px;
}
.button-3d-1:active::after {
border: 3px solid transparent;
border-top: 3px solid hsl(16, 100%, 30%);
border-bottom-width: 0px;
bottom: -3px;
}
最終效果:CodePen 3D Button 1
2. 3D按鈕2
對於這種圓柱形的按鈕,思路和上面矩形3D的按鈕類似,也是通過box-shadow
構造側面呈現立體感。爲了使效果更加真實,側面的顏色呈現漸變效果,越往下顏色越深,因此我們可以通過疊加多層box-shadow
來實現:
HTML:
<button class="button-3d-2">Circle!</button>
CSS:
.button-3d-2{
position: relative;
background: #ecd300;
background: radial-gradient(hsl(54, 100%, 50%), hsl(54, 100%, 40%));
font-size: 1.4rem;
text-shadow: 0 -1px 0 #c3af07;
color: white;
border: 1px solid hsl(54, 100%, 20%);
border-radius: 100%;
height: 120px;
width: 120px;
z-index: 4;
outline: none;
box-shadow: inset 0 1px 0 hsl(54, 100%, 50%),
0 2px 0 hsl(54, 100%, 20%),
0 3px 0 hsl(54, 100%, 18%),
0 4px 0 hsl(54, 100%, 16%),
0 5px 0 hsl(54, 100%, 14%),
0 6px 0 hsl(54, 100%, 12%),
0 7px 0 hsl(54, 100%, 10%),
0 8px 0 hsl(54, 100%, 8%),
0 9px 0 hsl(54, 100%, 6%);
}
當點擊按鈕的時候,通過下移按鈕和減少box-shadow
的層數來實現按鈕被按下的效果:
CSS:
.button-3d-2:active{
...
top: 2px;
box-shadow: inset 0 1px 0 hsl(54, 100%, 50%),
0 2px 0 hsl(54, 100%, 16%),
0 3px 0 hsl(54, 100%, 14%),
0 4px 0 hsl(54, 100%, 12%),
0 5px 0 hsl(54, 100%, 10%),
0 6px 0 hsl(54, 100%, 8%),
0 7px 0 hsl(54, 100%, 6%);
}
最終效果:CodePen 3D Button 2
3. 漸變按鈕1
提到漸變色大家一般都會想到background-image
屬性可以設置爲linear-gradient
以呈現漸變色的背景,事實上linear-gradient
的類型屬於<image>
的一種,所以凡是可以使用圖片的屬性都可以用linear-gradient
代替,包括border-image
。實現這個按鈕的關鍵在於實現一個漸變色和邊框,而且當鼠標懸浮的時候邊框和背景融爲一體。
首先,我們實現漸變色的邊框。
HTML:
<button class="gradient-button-1">Gradient Button 1</button>
CSS:
.gradient-button-1{
position: relative;
z-index: 1;
display: inline-block;
padding: 20px 40px;
font-size: 1.4rem;
box-sizing: border-box;
background-color: #e7eef1;
color: orangered;
border:solid 10px transparent;
border-image: linear-gradient(to top right, orangered, yellow);
}
效果:
很奇怪,只有四個頂點有圖像。這是因爲border-image-slice
默認爲100%,所以導致四條邊線上並沒有分配背景圖像。border-image-slice
的用法參考 MDN,簡而言之就是用四條(上下、左右各兩條平行線,想象一下九宮格火鍋。。)將圖片切割成9塊,在border的對應區域顯示對應的圖像切片,而border-image-slice
的值就是那四條線的偏移量。這下大家應該能理解偏移量爲100%的時候只有四個頂點上纔有圖片了吧。
所以我們需要調整border-image-slice
的值,鑑於border-image-source
爲linear-gradient
,我們需要將border-image-slice
的值設置爲1
(表示四條線的偏移量都爲1px)才能顯示連續的漸變色背景:
CSS:
.gradient-button-1{
...
border-image-slice: 1;
}
最後,我們只需要在鼠標懸浮的時候用漸變色填充按鈕內部就行了,此處有兩種實現,用 background-image
或者 將border-image-slice
設置爲 fill
(表示填充border中間的區域):
CSS:
.gradient-button-1:hover{
color: white;
background-image: linear-gradient(to top right, orangered, yellow);
/* 或者 */
border-image-slice: 1 fill;
}
最終效果:CodePen Gradient Button 1
4. 漸變按鈕2
與上一種按鈕類似,只不過顏色是逐漸變透明,實現也類似:
HTML:
<button class="gradient-button-2">Gradient Button 2</button>
CSS:
.gradient-button-2{
...
border:solid 4px transparent;
border-image: linear-gradient(to right, orangered, transparent);
border-image-slice: 1;
}
.gradient-button-2:hover{
color: white;
background-image: linear-gradient(to right, orangered, transparent);
border-right: none;
}
注意點:當hover的時候需要設置 border-right: none
,否則右側邊框無法呈現消失的狀態。
最終效果:CodePen Gradient Button 2
5. 動畫按鈕1
給按鈕加上一個動態背景的思路是:先找一個可以repeat的背景圖(可以去 siteorigin 生成),然後使用keyframe
自定義一段動畫,當鼠標懸浮在按鈕上的時候運行該動畫:
HTML:
<button class="animated-button-1">Animated Button 1</button>
CSS:
.animated-button-1{
position: relative;
display: inline-block;
padding: 20px 40px;
font-size: 1.4rem;
background-color: #00b3b4;
background-image: url("wave.png");
background-size: 46px 26px;
border: 1px solid #555;
color: white;
transition: all ease 0.3s;
}
.animated-button-1:hover{
animation: waving 2s linear infinite;
}
@keyframes waving{
from{
background-position: 0 0;
}
to{
background-position: 46px 0;
}
}
注意點:background-position
水平方向的值需要等於背景圖片的寬度或其整數倍,這樣動畫循環播放的時候首尾才能平穩過渡。
6. 動畫按鈕2
該按鈕的實現思路是:用 ::after
僞元素創建右側的箭頭,使用絕對定位固定在按鈕右側,靜止狀態下通過設置opacity: 0
隱藏,當鼠標懸浮時,增大按鈕的padding-right
,同時增加箭頭的不透明度,並將其位置往左移動:
HTML:
<button class="animated-button-2">Animated Button 2</button>
CSS:
.animated-button-2{
position: relative;
padding: 20px 40px;
font-size: 1.4rem;
background-color: #00b3b4;
background-size: 46px 26px;
border: 1px solid #555;
color: white;
transition: all ease 0.3s;
}
.animated-button-2::after{
position: absolute;
top: 50%;
right: 0.6em;
transform: translateY(-50%);
content: "»";
font-size: 1.2em;
transition: all ease 0.3s;
opacity: 0;
}
.animated-button-2:hover{
padding: 20px 60px 20px 20px;
}
.animated-button-2:hover::after{
right: 1.2em;
opacity: 1;
}
最終效果:CodePen Animated Button 2
7. 開關按鈕1
這算是一個挺常見的開關按鈕,它的實現思路是:
- 通過一個checkbox記錄開關的狀態,並隱藏該checkbox;
- 使用一個
<label>
作爲整個按鈕容器,並通過for
屬性與checkbox關聯,這樣點擊按鈕的任何地方都能改變checkbox的狀態; - 使用一個
<span>
作爲按鈕可視的部分,並作爲 checkbox 的相鄰元素,這樣通過 checkbox的僞類選擇器:checked
和相鄰選擇器+
選中<span>
並顯示不同狀態下的內容。
HTML:
<label for="toggle1" class="toggle1">
<input type="checkbox" id="toggle1" class="toggle1-input">
<span class="toggle1-button"></span>
</label>
CSS:
.toggle1{
font-family: Arial, Helvetica, sans-serif;
vertical-align: top;
width: 80px;
display: block;
margin: 100px auto;
}
.toggle1-input{
display: none;
}
.toggle1-button{
position: relative;
display: inline-block;
font-size: 1rem;
line-height: 20px;
text-transform: uppercase;
background-color: #f2395a;
border: 1px solid #f2395a;
color: white;
width: 100%;
height: 30px;
transition: all 0.3s ease;
cursor: pointer;
}
.toggle1-button::before{
position: absolute;
top: 5px;
left: 38px;
content: "off";
display: inline-block;
height: 20px;
padding: 0 3px;
background: white;
color: #f2395a;
transition: all 0.3s ease;
}
.toggle1-input:checked + .toggle1-button{
background: #00b3b4;
border-color: #00b3b4;
}
.toggle1-input:checked + .toggle1-button::before{
left: 5px;
content: 'on';
color: #00b3b4;
}
注意點:<label>
的for
屬性的作用;:checked
僞類的使用;+
相鄰選擇器的使用。
8. 開關按鈕2
與開關按鈕1類似,動畫效果上更簡單,只要切換顏色就行了:
HTML:
<label for="toggle2" class="toggle2">
<input type="checkbox" id="toggle2" class="toggle2-input">
<span class="toggle2-button">Click to activate</span>
</label>
CSS:
.toggle2{
font-family: Arial, Helvetica, sans-serif;
font-size: 0.8rem;
display: inline-block;
vertical-align: top;
margin: 0 15px 0 0;
}
.toggle2-input{
display: none;
}
.toggle2-button{
position: relative;
display: inline-block;
line-height: 20px;
text-transform: uppercase;
background: white;
color: #aaa;
border: 1px solid #ccc;
padding: 5px 10px 5px 30px;
transition: all 0.3s ease;
cursor: pointer;
}
.toggle2-button::before{
position: absolute;
top: 10px;
left: 10px;
display: inline-block;
width: 10px;
height: 10px;
background: #ccc;
content: "";
transition: all 0.3s ease;
border-radius: 50%;
}
.toggle2-input:checked + .toggle2-button{
background: #00b3b4;
border-color: #00b3b4;
color: white;
}
.toggle2-input:checked + .toggle2-button::before{
background: white;
}
本文參考:https://youtu.be/pmKyG3NBY_k