標籤:

自定義表單樣式實現(radio/checkbox/select)

雖然HTML在其標籤input的type屬性中提供了關於單選框和複選框的實現方法,並有標籤select用以實現下拉菜單,但是這些基礎形態往往無法滿足實際工作中的需求,而其中又封死了若干默認樣式,導致我們在複寫樣式時束手束腳。與其糾纏不如另闢蹊徑,下文將介紹這三種表單樣式的自定義寫法。

單選框 radio

單選框和複選框的核心思路類似,都是在原本的input之上用新的dom元素label覆蓋,隱藏前者而在後者上實現我們想要的樣式,兩者通過id與for相互關聯,多個radio之間通過name相互關聯。HTML片段如下:

<div class="nm-radio"> <input type="radio" id="radio1" name="radio" checked="checked"/> <label for="radio1"></label></div>

CSS的重點就在於label的樣式實現上,已筆者當前所寫系統樣式為例,需要實現一個圓環內包含一個實心圓的樣式,實心圓顯示時為選中狀態,CSS3的border-radius可以輕鬆實現,這裡將實心圓放在了label的before偽元素上:

.nm-radio { position: relative; width: 16px; height: 16px;}.nm-radio input { position: absolute; visibility: hidden}.nm-radio label { position: absolute; display: inline-block; width: 16px; height: 16px; border: 1px solid #d7d7d7; border-radius: 9px;}/*選中狀態*/.nm-radio input:checked + label { border: 1px solid #1baede;}.nm-radio input:checked + label:before { content: ""; position: absolute; top: 3px; left: 3px; width: 10px; height: 10px; border-radius: 5px; background-color: #1baede;}

如果項目還需要實現禁用狀態的話,在此基礎上加一些樣式覆蓋即可:

/*禁用狀態*/.nm-radio input:disabled + label { border: 1px solid #d7d7d7;}.nm-radio input:disabled + label:before { background-color: #d7d7d7}

複選框 checkbox

相較於單選框,複選框的實現雖然類似,但略複雜一些,主要體現在那個「勾」的實現上。先上基礎的CSS代碼:

.nm-checkbox { position: relative; width: 16px; height: 16px;}.nm-checkbox input { position: absolute; visibility: hidden;}.nm-checkbox label { position: absolute; display: inline-block; width: 16px; height: 16px; border: 1px solid #d7d7d7;}

當複選框處於選中狀態時,首先要改變其邊框顏色和背景色,然後在中間顯示出表示選中的勾,這個通過CSS3中2D轉換的rotate實現,即繪製一個空心的長方形框並只顯示其兩條邊,再將它進行一定角度的旋轉,便能完美地做出一個勾的形狀了,這裡將背景層放在before偽元素上、勾放在after偽元素上。

.nm-checkbox input:checked + label { border: 1px solid #1baede;}.nm-checkbox input:checked + label:before { content: ""; position: absolute; width: 16px; height: 16px; background-color: #1baede;}.nm-checkbox input:checked + label:after { content: ""; position: absolute; left: 2px;bottom: 6px; width: 8px;height: 4px; border: 2px solid #ffffff; border-top-color: transparent; border-right-color: transparent; -ms-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -webkit-transform: rotate(-45deg); transform: rotate(-45deg);}

禁用狀態的實現也與radio類似:

/*禁用狀態*/.nm-checkbox input:disabled + label { border: 1px solid #d7d7d7;}.nm-checkbox input:disabled + label, .nm-checkbox input:disabled + label:before { background-color: #d7d7d7;}

下拉菜單 select

在實現自定義下拉框時完全拋棄了select,而是用一個input和一個ul來模擬出它的樣子,當然用input是為了支持可輸入,如果不需要輸入的話隨便一些其他標籤也可以,另外還需要一個標籤i來模擬下拉的那個小箭頭:

<div class="nm-select"> <i></i> <input type="text" /> <ul> <li>1</li> <li>2</li> <li>3</li> </ul></div>

具體樣式可根據需求調整:

.nm-select { position: relative;}.nm-select input { height: 36px; width: 100%; padding: 3px 20px; margin: 0; border: 1px solid #cecece; border-radius: 4px; color: #333; box-sizing: border-box; font-size: 16px;}.nm-select i { position: absolute; top: 15px; right: 10px; width: 0; height: 0; border: 5px solid transparent; border-top-color: #b4b4b4; cursor: pointer}.nm-select ul { display: none; overflow: hidden; width: 100%; padding: 0; padding: 5px 0; margin: 2px 0 0 0; border: 1px solid #cecece; border-radius: 4px; box-shadow: 0 6px 12px rgba(0,0,0,.175)}.nm-select ul li { padding: 3px 20px; margin: 0; cursor: pointer; color: #333333;}.nm-select ul li:hover { background-color: #e9f7fc;}

實際應用中將通過MVVM框架的雙向綁定以及jquery來實現下拉框的賦值和動效,不在CSS的能力範圍內,而這裡可以先通過focus偽類來控制簡單的顯隱,以一個dom元素的事件來控制另一個元素的顯隱,也算是一個小技巧:

.nm-select input:focus + ul { display: block}

綜上所述,實現的效果截圖如下:

其實只要明白主要思路,實現起來都是非常簡單的事情。


推薦閱讀:

什麼是 CSS 架構?作為 CSS 架構師,每天的任務是什麼呢?
你的網站可以一鍵變色嗎?
你還在記css的賦值順序嗎?
前端組件化普及的今天花時間鑽研bootstrap3/AdminLTE2這些UI框架還能有多大收益?

TAG:CSS |