前端工程師和設(shè)計(jì)師一直都是相愛(ài)相殺的兩個(gè)人。
在拿到UI稿時(shí)設(shè)計(jì)師告訴我要做到99%還原。。。滿臉黑線( ̄工 ̄lll)于是乎,就要實(shí)現(xiàn)設(shè)計(jì)師滿意的checkbox。以下為實(shí)現(xiàn)步驟。
Requirement:
要實(shí)現(xiàn)如圖所示的checkbox:
Paste_Image.png
Implementation:
-
首先,需要讓設(shè)計(jì)師給你一張如下圖所示的png:
checkbox.png
這張圖片從左到右依次為,checkbox默認(rèn)狀態(tài)、hover狀態(tài)、選中狀態(tài)、未選中的disabled狀態(tài)、選中的disabled狀態(tài)。
- 接下來(lái)就要使用強(qiáng)大的CSS了。
首先給需要個(gè)性化的checkbox加上以下樣式:
input[type="checkbox"] {
-webkit-appearance: none; //去掉checkbox原有的樣式
}
然后利用設(shè)計(jì)師給的圖添加checkbox各種狀態(tài)所需要的樣式:
默認(rèn):
input[type="checkbox"] {
-webkit-appearance: none;
background: url("checkbox.png");
height: 16px; //每一個(gè)checkbox的高度
vertical-align: middle;
width: 16px; //每一個(gè)checkbox的寬度
}
選中:
input[type="checkbox"]:checked {
background-position: -36px 0; //圖片相對(duì)于當(dāng)前checkbox向左移16 + 2(間距) + 16px,即為選中樣式。
}
未選中:
input[type="checkbox"]:not(:checked) {
background-position: 0 0;
}
未選中hover:
input[type="checkbox"]:not(:checked):hover {
background-position: -18px 0;
}
選中但disabled:
input[type="checkbox"][disabled]:checked {
background-position: -72px 0;
}
其他樣式可以自己參考自己設(shè)定。 - 兼容性方面:
目前只兼容 Webkit 系列瀏覽器; Firefox 實(shí)現(xiàn)了替代的 -moz-appearance屬性,不過(guò)控件原有的背景顏色、邊框樣式無(wú)法修改;IE 系列暫時(shí)不支持該屬性。 - 為了兼容更多的主流瀏覽器,需要尋求另外的解決方案。
在所有主流瀏覽器里,點(diǎn)擊關(guān)聯(lián)某個(gè)復(fù)選框的 label 時(shí),產(chǎn)生的效果和點(diǎn)擊元素自身相同,會(huì)切換復(fù)選框控件的選中狀態(tài)。
既然能用 label 元素來(lái)控制復(fù)選框的狀態(tài),那就不必直接操作實(shí)際的復(fù)選框元素,而把操作和樣式都轉(zhuǎn)移到與之關(guān)聯(lián)的 label 元素上:
<input id="example" type="checkbox">
<label for="example"></label>
確保 label 元素的 for屬性的值和復(fù)選框 input 的 id值一致,同時(shí)將 label 元素放置于 input 之后,這樣 CSS 可以通過(guò)相鄰兄弟選擇器定位到這個(gè) label 元素并為之應(yīng)用樣式:
input[type="checkbox"] + label:before {
background: #fff url(i/blue.png);
content: " ";
height: 22px;
left: 0;
position: absolute;
width: 22px;
}
有了樣式化的 label 元素來(lái)提供交互,原生的 checkbox 控件就顯得有點(diǎn)多余了,雖然可以用 display: none把它隱藏掉,不過(guò)隱藏后的表單元素是不能獲得焦點(diǎn)的,要怎么辦呢?
當(dāng)然,沒(méi)有什么問(wèn)題用一個(gè)div解決不了的。所以我們做如下修改:
<div class="checkbox">
<input id="exampleCheckbox" type="checkbox">
<label for="exampleCheckbox"></label>
</div>
/* css */
.checkbox {
min-height: 24px;
padding-left: 24px;
position: relative;
}
input[type="checkbox"] {
box-sizing: border-box;
left: 4px;
margin: 0;
padding: 0;
position: absolute;
top: 3px;
}
用一個(gè)div將label和input包含在內(nèi),并設(shè)置div的position為relative,這樣就可以調(diào)整label和checkbox相對(duì)于父div的位置,實(shí)現(xiàn)用 label 元素把checkbox遮住,這樣既能支持鍵盤交互,同時(shí)當(dāng)圖片加載失敗的時(shí)候,又能保證原生的控件可用。
這樣就可以兼容主流瀏覽器啦。
有一個(gè)iCheck庫(kù),可以實(shí)現(xiàn)很好看的checkbox樣式,詳見(jiàn)使用說(shuō)明-中文。但是要實(shí)現(xiàn)各家設(shè)計(jì)師的樣式,還是要自力更生呀。(? ? ?)