在各類UI組件庫大行其道的今天,你們已經不多本身用CSS去實現一些效果了,長此以往CSS的水平也愈來愈退步,因此有空仍是得練練。今天給你們分享8種炫酷按鈕的CSS實現。動畫
如今的主流是扁平化的設計,擬物化的設計比較少見了,因此咱們僅從技術角度去分析如何實現這個3D按鈕(文中只列出各類實現的關鍵代碼,完整代碼請參考CodePen)。url
該按鈕的立體效果主要由按鈕多出的左、下兩個側面陪襯出來,咱們可使用box-shadow
模擬出這兩個側面:spa
HTML:設計
<button class="button-3d-1">3D Button 1</button>
CSS:3d
.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%); }
效果:code
加了box-shadow
以後總體形狀有點像了,可是立方體的左上和右下確缺了一塊。經過觀察咱們發現,缺的這兩塊是三角形的,因此若是咱們能構造兩個三角形補到這兩個角上就好了。用CSS畫三角形對你們來講應該是基本操做了,若是還有同窗不知道,下面的動畫很好的解釋了原理(代碼參考 Triangle):orm
咱們使用::before
和::after
僞元素來分別繪製左上、右下的兩個三角形,並經過絕對定位將它們固定到兩個角落:blog
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
的偏移量以達到按鈕底部固定不動的效果:ci
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; }
對於這種圓柱形的按鈕,思路和上面矩形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%); }
提到漸變色你們通常都會想到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; }
與上一種按鈕相似,只不過顏色是逐漸變透明,實現也相似:
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
,不然右側邊框沒法呈現消失的狀態。
給按鈕加上一個動態背景的思路是:先找一個能夠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
水平方向的值須要等於背景圖片的寬度或其整數倍,這樣動畫循環播放的時候首尾才能平穩過渡。
該按鈕的實現思路是:用 ::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; }
這算是一個挺常見的開關按鈕,它的實現思路是:
<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{ 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
僞類的使用;+
相鄰選擇器的使用。
與開關按鈕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-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