今早搭完電梯出來信號不太好,切換飛行模式重啟信號,發現iOS的「開關按鈕」挺好玩的,順便用純CSS實現一番。
思路外觀
按鈕,顧名思義就是可點擊觸發某些事件的組件。在HTML眾多標籤中可用<div>、<a>、<button>和<input>作為載體。
在四個常用標籤中只有<a>和<input>存在滑鼠觸發事件的狀態,因此只能從它倆中選擇。
「a」::link、:visited、:hover、:active<a>的HTML語義是「anchor」,代表超連結,提供的全部選擇器用於捕獲超連結的觸發狀態。
<input>的HTML語義是「input」,類型設置為radio或checkbox時代表選擇表單,提供的選擇器:checked用於捕獲選擇表單是否被選中。
很明顯,按鈕存在未點擊和已點擊兩種狀態,故選擇<input>作為載體。
<input>的類型設置為radio或checkbox是存在差別的。radio表示單選,若是單個存在,點擊選中後就無法再次點擊取消選中。checkbox表示多選,若是單個存在,點擊選中後還可再次點擊取消選中。故選擇類型為checkbox較為合適。
<input class="ios-switch" type="checkbox">從上述兩張截圖可抽象出iOS開關按鈕具有以下屬性的類,這個類可繼承到內部細節中。
.btn {
border-radius: 31px;
width: 102px;
height: 62px;
background-color: #e9e9eb;
}iOS開關按鈕是一個具有美感的組件,故把<input>醜陋的默認外觀抹除,細節地方就按照截圖自行設計。按鈕內的圓點在滑鼠懸浮時需出現手型光標,點擊後移動定位且移動效果最好有過渡動畫才不顯得生硬。
.ios-switch {
position: relative;
appearance: none;
cursor: pointer;
transition: all 100ms;
@extend .btn;
}背景
筆者是一位天秤座男生,對細節特別摳,細心和負責是筆者在工作上得到肯定的標籤。細心的同學可能會發現iOS開關按鈕在打開過程中,其背景存在著細微的變化。
「細微變化」:灰色的背景區域快速縮小並顯示綠色的背景區域過渡動畫的貝塞爾曲線可用https://cubic-bezier.com微調到你想要的效果。
為了不引入太多HTML標籤,iOS開關按鈕的背景使用偽元素::before代替。
.ios-switch {
&::before {
position: absolute;
content: "";
transition: all 300ms cubic-bezier(.45, 1, .4, 1);
@extend .btn;
}
}圓點
圓點不用多說,就是一個圓圓的點。為了讓過渡動畫更生動,給它加了一個剎車回彈的細微動畫,物理術語叫做「慣性回彈」。
試想像一塊大大的果凍,在運行過程中突然急剎,前面那部分果凍因為慣性會向前擠,由於內部的柔韌性和分子牽引又將其拉回來。
這個慣性回彈動畫可用貝塞爾曲線實現。一行代碼實現慣性回彈厲害不,當然你也可用在其他動畫場景上。
.elem {
transition: all 300ms cubic-bezier(.4, .4, .25, 1.35);
}圓點的實現幾乎沒難度,只需加一個動畫讓其過渡起來更生動。貝塞爾曲線動畫可參考其他專業文章學習,在此就不再敘述了。另外,稍加一個小陰影潤色下,讓其看起來更立體。
為了不引入太多HTML標籤,iOS開關按鈕的圓點使用偽元素::after代替。
.ios-switch {
&::after {
position: absolute;
left: 4px;
top: 4px;
border-radius: 27px;
width: 54px;
height: 54px;
background-color: #fff;
box-shadow: 1px 1px 5px rgba(#000, .3);
content: "";
transition: all 300ms cubic-bezier(.4, .4, .25, 1.35);
}
}過渡
這個思路是重中之重,按鈕點擊進入選中狀態會觸發:checked,在:checked下對::before和::after做文章即可。結合上述涉及到點擊後的細節,完善其餘屬性即可。
.ios-switch {
&:checked {
background-color: #5eb662;
&::before {
transform: scale(0);
}
&::after {
transform: translateX(40px);
}
}
}
效果最終完成效果如下。非常貼切今天的主題:「iOS開關按鈕,純CSS給你安排上了」。
整體源碼如下。
<input class="ios-switch" type="checkbox">.btn {
border-radius: 31px;
width: 102px;
height: 62px;
background-color: #e9e9eb;
}
.ios-switch {
position: relative;
appearance: none;
cursor: pointer;
transition: all 100ms;
@extend .btn;
&::before {
position: absolute;
content: "";
transition: all 300ms cubic-bezier(.45, 1, .4, 1);
@extend .btn;
}
&::after {
position: absolute;
left: 4px;
top: 4px;
border-radius: 27px;
width: 54px;
height: 54px;
background-color: #fff;
box-shadow: 1px 1px 5px rgba(#000, .3);
content: "";
transition: all 300ms cubic-bezier(.4, .4, .25, 1.35);
}
&:checked {
background-color: #5eb662;
&::before {
transform: scale(0);
}
&::after {
transform: translateX(40px);
}
}
}點擊「閱讀原文」可查看在線演示和在線源碼喔!關注「IQ前端」,更多CSS神操作騷技巧等著你學習。