長久以來,我一直有的問題,就是表單裡面的radio和checkbox在樣式上難道就只能那樣嗎?在IE裡雖然可以給他加上border、background-color這一些性質,但是出來的效果卻是...,唉,不說也罷,有興趣的人可以自己試試看,沒看過的可能會嚇一跳吧。不過這個問題,終於在這兩天有了初步的解決的,雖然和我最初的希望不一樣,不過事實上自由度更大了,而且我很滿意這個效果,效果就像是現在本站發表迴響那,「記錄個人資訊?」那裡一樣。這都要歸功於強大的CSS和<label />標籤,CSS3的:checked擬類別(Pseudo-Classes)配合+這個CSS2就有的氏族選擇器(Asjacent Sibling Selector)和<label />標籤就可以達到我要的效果了,如果要效果更完整,還可以加上opacity(透明度)這個性質(property)。當然,因為是歸功於CSS3,所以IE使用者就無緣看到這有趣的效果了。
接下來,就來一步一步的設計吧,如果想用在checkbox上面也可以如法泡製。首先先做出一個form物件和裡面的radio物件,以及配合radio的label,當然為了能讓label指向,每個radio都要有獨立的id,詳見範例一,如果沒用過<label />標籤的人,可以趁這機會測試一下<label />的功用,你只要在First Selection、Second Selection、Third Selection三個文字上用滑鼠點選,對應的選項就會直接被選取了,當然,你要確定radio的id和label的for一樣,事實上<label />並沒有限定它能指向的元素型態,基本上是任意物件都可以,只要你有給它指定獨立的id,只是有些物件你指定了也沒什麼用,HTML的部分在這裡就已經確定成型了,接下來我們只會針對CSS的部份作修改。
再下來一步,我們要來替label標籤加上樣式,不過為了和其他非指向radio的label做區別,我們在這裡要上用+這個選擇器還有CSS 2已經有的屬性選擇器,CSS碼長的像下面這樣。
input[type="radio"]+label
{
border: 2px solid #66f;
padding: 1px 3px;
background-color: #ffe;
}
我們把第一行的部分單獨抓出來解釋,input[type="radio"]+label
,這行的意思是:「選擇接在input物件後面的label物件,其中,input物件的type屬性值要等於radio
。」,如果能瞭解是最好,不能瞭解的話也沒關係,以後慢慢弄清楚DOM就可以了,現在照著用就沒問題。再來一樣是為label上style,不過這次我們要讓被選取的選項能辨識出來,這裡我們用到了checked這個擬類別,只看選擇物件的部份,input[type="radio"]:checked+label
,這就表示只選擇被選取的radio後面的label物件。詳細請見範例二,你可以任意選取選項看看,選取的選項的<label />馬上就會變色了。
接下來是重點了,我們要把radio物件給隱藏起來,用的方法很簡單,只是margin性質,只不過是比較少用的負margin值,順便也為了讓使用者知道<label />是可以選取的,所以加上:hover的效果,要特別注意的是設定hover的地方有兩個,結果請見範例三。為什麼input的長度是3em,它的margin-right卻是-3.3em,為什麼多了0.3em,我也不知道 orz,我測試的結果是設剛剛好3em會無法把radio蓋住,所以加到3.3em。
光是以上的設計還會有些問題,要是label的背景色是透明怎麼辦,被蓋在後面的radio不是就會冒出來了嗎?請見範例四。所以我們還要把radio給隱藏起來,可以用的方法有三種,display: none;
、visibility: hidden;
、opacity: 0;
,在這裡我選擇了第三種,因為親合力的問題,如果我選擇了前兩種,即使我設定tabindex給他,我都無法用Tab鍵把focus移到該選項上,要是又沒有設定accesskey,那狀況就會變的不太好,使用者只要無法控制滑鼠,就沒辦法對你的radio和checkbox做選擇,因此我把它隱藏起來的方法選擇讓他完全透明。而為了讓使用者能知道他的游標移到哪個選項,所以我們利用:focus
這個擬類別來對label作樣式的變化,結果請見範例五,在這個範例裡你會發現即使底色都是透明的,input物件也都看不到了,不過你仍然可以用Tab來切換選項。
作到這邊,我們就完成了,你可以看到最後的結果,下面列出了完整的HTML和全部的CSS碼,最後要提醒的就是<label />裡面可以放的不只是文字,只是你必須要注意到一件事,就是使用者能夠一眼看到就知道它可以選,我的方法是先勾選一個預設值,讓他能和其他選項明顯不同,使用者能一眼就注意到,不過這方法比較適用於radio,如果是checkbox我就沒還沒有想到簡單的方法了,不過也是可以配合background-image之類的性質。如果有誤還請指正,或是有更好的方案也歡迎討論。