之前製作「本站開放留言上傳圖片功能」時,才發現 Input 上傳檔案按鈕還真不是普通地難搞。查了一下發現 Google 這些字串 "input type file css not working"時會有不少案例,很是離奇。
好在最後還是找到完美的解決方法,以下大致說明這是什麼狀況,並提供幾個實作範例。
(圖片出處: pixabay.com)
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 file 檔案上傳按鈕」。
1. 最佳解法 1
前面提到的討論串「Styling an input type=“file” button」,裡面第二個解答,沒有被評為最佳解答,但獲得最多的推薦,其實就是本篇的最佳解。
他的原理是:
2. 最佳解法 2
但作者有說到兩個缺點:
如果是以上這些狀況,作者提供的解法也很簡單,不要隱藏 input 上傳按鈕,把尺寸設定為 1px 大小,位置用 position 挪到看不到的地方就好。
他提供了這兩個範例程式碼:
3. 其他應用
瞭解 Label 的原理後,像 input 核取方塊(checkbox)、單選按鈕(radio),都可以用同樣的方式,用 Label 把核取方塊、單選按鈕,以及描述文字通通包起來,這樣就很方便訪客點擊了,就像這樣:
上面這個上傳按鈕,就是本站留言板上方會出現的按鈕樣式,結合了「Bootstrap」、「Font Awesome 圖示」,範例程式碼如下:
這個按鈕做起來輕鬆又愉快,不用搞複雜的 CSS 技巧,也不需要製作圖片。
這是做另一個案子用到的上傳圖片按鈕範例,同樣非常實用,比較常見於用在上傳會員頭像的區塊。
範例程式碼如下:
這個功能雖然稍微比較複雜,需要利用 position 設定各種定位,不過對於理解 input 包在 label 之中的用法幫助很大,是很實用的技巧。
好在最後還是找到完美的解決方法,以下大致說明這是什麼狀況,並提供幾個實作範例。
(圖片出處: pixabay.com)
一、為何 Input Type="file"不給修改
1. CSS 沒辦法改
一開始是發現滑鼠移到上傳按鈕時,依然是游標圖示,且無法改為手掌點擊的圖示,就像下面這樣:
最簡單的 CSS 參數
不只如此,看到另一個討論串「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 相關技巧: