2017年10月1日 星期日

自訂 Input File 檔案上傳按鈕 CSS 最佳解法﹍實作範例

自訂 Input File 檔案上傳按鈕 CSS 最佳解法﹍實作範例

Wayne Fu 0 A+
之前製作「本站開放留言上傳圖片功能」時,才發現 Input 上傳檔案按鈕還真不是普通地難搞。查了一下發現 Google 這些字串 "input type file css not working" 時會有不少案例,很是離奇。

好在最後還是找到完美的解決方法,以下大致說明這是什麼狀況,並提供幾個實作範例。

(圖片出處: pixabay.com)


一、為何 Input Type="file" 不給修改


1. CSS 沒辦法改

一開始是發現滑鼠移到上傳按鈕時,依然是游標圖示,且無法改為手掌點擊的圖示,就像下面這樣:





最簡單的 CSS 參數 cursor: pointer 是沒有作用的,查了一下看到這個討論串「Cursor pointer on a file input, possible?」,說可能是因為安全性的因素,各種瀏覽器都不會有作用。

不只如此,看到另一個討論串「Styling an input type=“file” button」,說要修改 input type="file" 的 CSS 樣式是異常的困難!而且連部分 js 都被禁止!!


2. 變通方法很麻煩

這下真的很棘手,我還不想為了這個小小的功能另外裝外掛或執行 js。

馬上想得到的思路大致是把 input 上傳按鈕變透明,放一張圖片在 input 按鈕下面,利用 position 定位來調整大小、位置等等,總可以將圖片喬到一個滿意的尺寸,可以剛好跟按鈕重疊。

調整過程其實滿繁複的:

  • 如果嫌麻煩把 input 上傳按鈕隱藏起來,例如 display: none,結果又會導致上傳功能失效。
  • 如果沒把圖片尺寸調得跟透明 input 按鈕完全一致,有時雖然視覺上看起來版面沒問題
  • 事實上不小心點到空白處仍可能點到透明 input 按鈕,就會彈出上傳視窗,讓使用者一頭霧水

變通方法的範例程式碼就不列出來了,各個相關討論串、文章幾乎都找得到,例如這個「自訂 input file 檔案上傳按鈕」。



二、Label 的妙用


1. 最佳解法 1

前面提到的討論串「Styling an input type=“file” button」,裡面第二個解答,沒有被評為最佳解答,但獲得最多的推薦,其實就是本篇的最佳解。

他的原理是:

  • Label 標籤有一個奇特的特性,只要他包在任何 Input 標籤外面,點擊 Label 就等於點擊 Input
  • 所以當 Label 標籤很寬、很大時,點擊 Input 就很方便
  • 利用這個特性,將 Label 標籤包在 input 上傳按鈕外面,再將 input 上傳按鈕隱藏起來,點擊依然有效
  • 接著想要使用圖片代替 Input 上傳按鈕的話,就可在 Label 裡面放圖片
  • 原本對 input 上傳按鈕無法設定的任何 CSS,此時設定在 Label 上即可。


2. 最佳解法 2

但作者有說到兩個缺點:

  • IE8 不接受 input 上傳按鈕被隱藏起來
  • 如果使用「表單驗證」這類外掛時,隱藏的表單不會被驗證。

如果是以上這些狀況,作者提供的解法也很簡單,不要隱藏 input 上傳按鈕,把尺寸設定為 1px 大小,位置用 position 挪到看不到的地方就好。

他提供了這兩個範例程式碼:



3. 其他應用

瞭解 Label 的原理後,像 input 核取方塊(checkbox)、單選按鈕(radio),都可以用同樣的方式,用 Label 把核取方塊、單選按鈕,以及描述文字通通包起來,這樣就很方便訪客點擊了,就像這樣:






三、input 上傳按鈕實作範例 1




上面這個上傳按鈕,就是本站留言板上方會出現的按鈕樣式,結合了「Bootstrap」、「Font Awesome 圖示」,範例程式碼如下:

<label class="btn btn-info">
<input id="upload_img" style="display:none;" type="file">
<i class="fa fa-photo"></i> 上傳圖片
</label>

  • 首先將 input 上傳按鈕包在 label 之中,並將 input 按鈕隱藏
  • label 加了這幾個 class 可以自動產生漂亮美觀的按鈕
  • 文字 "上傳圖片" 左邊的 HTML 碼是 Font Awesome 對應的圖示

這個按鈕做起來輕鬆又愉快,不用搞複雜的 CSS 技巧,也不需要製作圖片。



四、input 上傳按鈕實作範例 2


這是做另一個案子用到的上傳圖片按鈕範例,同樣非常實用,比較常見於用在上傳會員頭像的區塊。



範例程式碼如下:

<label class="upload_cover">
<input id="upload_input" type="file">
<span class="upload_icon">➕</span>
<i class="delAvatar fa fa-times-circle-o" title="刪除"></i>
</label>
<style>
.upload_cover {
position: relative;
width: 100px;
height: 100px;
text-align: center;
cursor: pointer;
background: #efefef;
border: 1px solid #595656;
}
#upload_input {
display: none;
}
.upload_icon {
font-weight: bold;
font-size: 180%;
position: absolute;
left: 0;
width: 100%;
top: 20%;
}
.delAvatar {
position: absolute;
right: 2px;
top: 2px;
}
</style>


  • 首先將 input 上傳按鈕包在 label 之中,並將 input 按鈕隱藏
  • label 設定整個正方形頭像區塊的 CSS,例如前面提到的 cursor pointer,以及外框、底色等。
  • 中間的 "十字" 圖示是利用「Unicode 特殊符號字元」,用來提示使用者按了可以上傳圖片
  • 右上角的打叉圖示,使用 Font Awesome,用來提示使用者按了可以取消這張圖片,重新上傳。

這個功能雖然稍微比較複雜,需要利用 position 設定各種定位,不過對於理解 input 包在 label 之中的用法幫助很大,是很實用的技巧。


更多 CSS 相關技巧:
0 0
如這篇文章對你有幫助,歡迎「分享」到 FB、「追蹤」粉絲團、「訂閱」最新文章
TOP