Re從零開始的UI庫編寫生活之按鈕

FlyTeng_1874發表於2019-06-18

構想

按鈕元件是UI庫中最基礎的元件之一,所以這個元件應該儘可能靈活地提供可配置項,那我們怎樣才能輕鬆便捷地去配置按鈕呢?有兩種方法,一種是通過js去獲取按鈕的屬性,從而為不同型別的按鈕加上相應的樣式,第二種則是通過css的選擇器去匹配所配置的樣式,從而利用樣式去控制按鈕的表達,很明顯第二種方案能將按鈕元件從js中剝離解耦,更加能達到理想中的效果。

image
image

使用純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去實現的)

image

//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類。

image

//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 首頁的按鈕標籤中能找到,還有很多欠缺的地方,歡迎多多交流。以後會有更多新奇好玩的東西越來越多地融入其中。

image

image

從零開始系列傳送門

相關文章