radio模仿單選select

radio2select抓圖

為什麼要用radio模仿select呢,因為select標籤也是沒辦法完全依照自己希望設定樣式的物件之一,舉例來說,他的邊框我就沒辦法設定。因此我一直在尋找方法來處理這個問題,直到想到之前的:checked應用的方法之後,才似乎出現了一絲署光,不過一直拖到最近才有座法的構想,沒想到實際做起來還是遇到不少問題,但還是做出了一個可以用的版本,雖然還有些問題。

接著我們來看看這是怎麼做到的,為了模仿select標籤,我們的要求有幾個:

  1. 滑鼠移過去時選項會垂直展開(很可惜做不到點選式的)。
  2. 展開時會浮在下方物件的上面,不會因此而把物件往下推。
  3. 可以只用鍵盤做到選擇選項(親合力)。
  4. inline物件。

首先簡單的把radio物件和label標籤列出來,如範例一,接著我們要把radio隱藏起來,讓label垂直條列,隱藏radio用的方法和以前一樣,讓label垂直條列我是用float+clear的方法來達成,當然,還是要配合+選擇子,結果如範例二,其中radio的style需要特別說明一下:

input[type='radio']
{
	opacity: 0;
	margin-bottom: -2em;
	float: left;
	clear: left;
}

和之前的:checked應用不一樣,因為float和clear的設定,radio和label會一個一個交錯的疊在一起,看起來就像範例二之一一樣,接著設定margin-bottom為"-2em",目的是為了讓radio物件下方的東西能和他完全重疊,就變成範例二之二的樣子,,在這個範例裡我把label的底色改成透明,好讓大家能看到現在radio的位置。接著設定opacity就可以讓radio隱藏起來。

再來我們設定一下:hover和:checked的樣式,好讓我們能清楚判斷現在選項的狀況,這部分主要是選擇子的設定,就不詳細說明,詳見範例三。在來是要求之ㄧ的展開效果了,在範例一的HTML碼裡面可以看到radio和label外面有一層span標籤,基本上我們就是利用它來針對我們要處理的label標籤做選擇的,結果如範例四,這時候已經有展開動作了,但是還會把下面的東西推開,所以接下來我們就針對這點來做修改,而範例四中其他關於border的設定,是為了把兩個label間較粗的邊框改成和旁邊一樣細的邊框。

要讓label可以浮在其他物件的上面,我們要更改的就是他的margin值,我的想法是把class=select的那個span物件的margin-bottom設成-100%,我們先來看看這樣子會發生什麼事,請見範例五之一,可以見到,之前會影響到下方排版的問題已經解決了,但是select物件卻和後面的按鈕重疊在一起了,這是因為我的margin: -100%;的設定讓select物件在版面中不佔任何空間,所以本來應該排在後面的按鈕就往前移動了,為了解決這個問題,我必須被迫增加一層span標籤(這是我不滿的第一點),或許有人會說可以設定動態的margin值,讓它剛好有點高度,但是問題是我不知道會有幾個選項,如果選項數固定的話,確實可以這樣做,但是這樣對於未來的維護實在不方便,所以我不採用這個方法。範例五,是我多加一層span並且已經把該有的css設定都弄上了,結果完全OK,CSS CODE如下。

span.select>span
{
	display: block;
	margin-bottom: -100%;
	position: relative;
}
span.select
{
	display: block;
	float: left;
	height: 1px;
}

我指定外層的span的height=1px,然後之前對於select物件的設定全部給內層的span,結果就是一個1px高的block物件裡面包著一個0px高的block物件,外層是用來製造寬度,內層是用來讓它的高度等於0。於是四個目標達成了兩個,接著便是鍵盤的控制了。

要讓鍵盤能操控,只要用上focus,讓tab鍵移動游標到該選項時使用者能知道,不過我再配合:after虛擬選擇器和content屬性質,增加一點提示,結果如範例六,這時大家可以試試看用tab和空白鍵更換選擇看看,不過唯一需要注意的是這裡新增的CSS值必須要放在範例四的span.select:hover label的設定前面,不然margin值會有錯誤,當然你也可以選擇不要修改margin,這樣要放哪都可以(吧XD)。

終於,只剩下最後一個目標了,讓它是inline物件,放在它後面的東西看起來沒問題,但是放在它前面的呢?就先來看看會怎樣吧,範例七之ㄧ,果然,變亂了...orz,這個問題,我想了很久要如何解決,最後,只能讓它前面的文字也是float:left;(這是第二個我不滿的地方),於是我新增了一個class叫label,範例七

終於,四個目標都達到了,完整的HTML和CSS見最後一個範例,雖然還有些覺得還可以改進的地方,而且Opera會亂掉,不過因為用了一些蠻有趣的技巧,所以還是把它寫出來了,延伸的用法,可以看看應用