構想
按鈕元件是UI庫中最基礎的元件之一,所以這個元件應該儘可能靈活地提供可配置項,那我們怎樣才能輕鬆便捷地去配置按鈕呢?有兩種方法,一種是通過js去獲取按鈕的屬性,從而為不同型別的按鈕加上相應的樣式,第二種則是通過css的選擇器去匹配所配置的樣式,從而利用樣式去控制按鈕的表達,很明顯第二種方案能將按鈕元件從js中剝離解耦,更加能達到理想中的效果。
使用純css去控制按鈕基本上就可以滿足業務的開發,不要擔心這個問題,除非是一些非常定製化的需求。
按鈕的設計
基礎結構
首先,根據想要達到的效果,可以這樣去寫一個按鈕
//btn.html
<button className="btn-normal">SluckyUI</button>
複製程式碼
//btn.css
.btn-normal{
display: inline-block;
border-radius: 3px;
text-align: center;
cursor: pointer;
outline: none !important;
position: relative;
overflow: hidden;
border: none;
}
複製程式碼
很簡單,一個按鈕就這樣成型了。
但新的問題又出現了,在平常的業務開發中,這樣一個簡單的按鈕是不足以支撐開發的,因為一個功能完備的按鈕通常會有一些額外的屬性和狀態,比如等待狀態,比如禁止點選狀態。然而css偽類是無法去‘監聽’這些狀態的生命週期的,那應該怎麼辦呢?
答案就是通過屬性去控制按鈕的狀態(類似於暴露一個介面,只不過這個介面是由css去實現的)
//btn.css
[loading='true']{
width: 25px;
height: 25px;
animation: loadingTypeA infinite .75s linear;
border: 2px solid #888;
border-top-color: transparent;
border-radius: 100%;
}
[disabled='true']{
...
}
@keyframes loadingTypeA {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
//btn.html
<button className="btn-normal" loading='true'>SluckyUI</button>
複製程式碼
這樣我們就可以通過loading屬性的值去控制按鈕的樣式(狀態),無論在react還是vue,angular中,我們都能很輕鬆地去控制。當然到這個步驟就並非純css了,我們需要在業務邏輯中去控制這個元件,畢竟這些元件的生命週期狀態是無法單靠css去走完一個完整的流程的。
Note:雖然可以通過樣式去靈活配置所需的效果,但還是建議在同一套UI中統一制定出s,m,l三種size,這樣更能在團隊中配合使用。
動畫特效
動畫特效是元件必不可少的互動之一,能給與使用者良好的互動體驗。而幾乎所有的效果都可以封裝成css類。
//animate.scss
//下劃線動畫,因為已經與具體的元件完全解耦,這些動畫可以用在任何元件中,後面會有專門的章節聊一聊神奇的動畫
.regularLineMove {
&::before {
content: "";
position: absolute;
right: 0;
bottom: 0;
width: 0;
height: 1px;
background-color: #000;
transition: .2s all;
}
&:hover::before {
left: 0;
width: 100%;
}
}
//btn.html
<button className="btn-normal regularLineMove">SluckyUI</button>
複製程式碼
按鈕加上regularLineMove動畫類之後,當滑鼠懸浮上去,就會有下劃線效果出現了。
但為什麼說是幾乎所有效果呢?因為僅靠css無法對display設定為none前作出有效的響應,比如淡出效果。細節會在彈窗篇裡講到。
進一步完善我們的按鈕
一個完善的按鈕元件應該能應對大部分情況,減輕我們的開發量。 比如當按鈕處於disabled狀態時,滑鼠應該要顯示一個禁止的標誌,並且按鈕顏色也應該要做出相應的改變等等。下面我們將大部分可能遇到的情況封裝一下。
// btn.scss
.btn-status {
//滑鼠普通懸浮
cursor: pointer;
//禁止狀態
&:disabled {
cursor: not-allowed;
background-color: $disable !important;
}
//點選後的狀態
&:active {
opacity: .8;
}
//將不美觀的樣式去除
outline: none !important;
&:focus {
outline: none !important;
}
...
}
複製程式碼
Bingo,就這樣button元件就基本設計好了,其實並不複雜,就是要考慮的情況比較多。
結尾
這些元件的想法已經實踐到了 SluckyUI 當中,更多有趣的按鈕效果能在 SluckyUI 首頁的按鈕標籤中能找到,還有很多欠缺的地方,歡迎多多交流。以後會有更多新奇好玩的東西越來越多地融入其中。
從零開始系列傳送門
- 《Re從零開始的UI庫編寫生活之規範制定》
- 《Re從零開始的UI庫編寫生活之按鈕》
- 《Re從零開始的UI庫編寫生活之表單》
- 《Re從零開始的UI庫編寫生活之表格》
- 《Re從零開始的UI庫編寫生活之載入進度條》
- 《Re從零開始的UI庫編寫生活之分頁》
- 《Re從零開始的UI庫編寫生活之選單導航欄》
- 《Re從零開始的UI庫編寫生活之訊息彈窗》
- 《Re從零開始的UI庫編寫生活之步驟管理器》
- 《Re從零開始的UI庫編寫生活之麵包屑》
- 《Re從零開始的webpack4實用向全實踐》
- 《Re從零開始的高效React+Redux專案架構搭建》
- Re從零開始的後端學習之配置Ubuntu+Ngnix+Nodejs+Mysql環境