仕事でスマホサイトのアップロードボタンを作成したときに、少し躓いたことがあったのでまとめてみようと思います。
そもそもデフォルトのデザインから変更できるのか?という疑問があったのですが、いろいろなサイトで変更されていることもあるので、とりあえず調べてみました。
ざっくり調べて、ざっくり理解したところによると…
ボタンとinputタグを別に記述して、javascriptでイベントを実行する!
これで出来るだろうと思ったので、ボタン部分をpタグで作成してinputタグをcssのdisplay: noneで非表示に変えて、jQueryでイベントを発生させる方法で進めることにしました。
そして、最初にできたコードが下記になります。
■HTML
<input type="file" id="decorate">
<div class="upload">
<p>UPLOAD</p>
</div>
■JS
$(document).ready(function(){
$('.upload').on('click', function(){
$('#decorate').trigger('click');
});
});
■CSS
#decorate {
display: none;
}
.upload {
border: solid 1px #a3ffa3;
background-color: #b7ffb7;
width: 200px;
text-align: center;
border-radius: 10px;
}
inputタグには、idをつけておきCSSでdisplay: noneすることで、inputタグはあるけど表示していない状態にしています。
JSでは、classにuploadが指定されているdivタグがクリックされたときに、非表示にしてあるinputタグに対して、clickイベントを発生させるようにしてあります。
この部分が完成して、iPhoneで確認したところ無事に想定通りの動作をしてくれました!
iPhoneでの確認ができて、意外と簡単にできたなーと思いながら、Androidで確認してみると…
事件が発生しました。
何度、ボタンを押してもなにも起こらない。。
うんとも、すんともいわない。
ガーンッと意気消沈しながらも、なにが問題なのかを確認するためにdisplay: noneをコメントアウトして確認してみると、ファイルを選択できることが発覚!
ということは、display: noneだとAndroidはダメなのか。。詰んだな。
一瞬、うん、諦めようという思いが湧いたような湧かなかったような…と、どうでも良い間がありつつ再度、調べてみると初見のvisibilityというプロパティを発見!
ざっくり説明するとdisplay: noneは、要素自体がなくなってしまうのですが、visibility: hiddenの場合は要素を残したまま非表示にすることができるというものです。
ということで、早速、display: noneからvisibility: hiddenに変更
■CSS
#decorate {
visibility: hidden;
}
頼む!と思いを込めて、ボタンをタップすると…
無事にファイルを選択できました!
ほっと安心するも、非表示にしただけなのでデフォルトのサイズ分要素が存在していて、その部分が空白になってしいました。。
新たな問題発生。ですが、これはサイズを0にすれば大丈夫だろうと思ったので、cssでheightとwidthを0pxに変更
■CSS
#decorate {
visibility: hidden;
height: 0px;
width: 0px;
}
もう一度、確認してみるとAndroidは想定通りだったのですが、iPhoneは変わりませんでした。。
ChromeのWEBインスペクタで確認してみると、各プロパティは適用されていることになっているのですが、見栄えはNG。
0pxがダメなら、1pxはどうなんだろうと思い1pxにしてみると今度は想定通りに変更することができました。
visibilityで非表示にしているので、1px存在してもボタンと重なる位置であれば、大丈夫なので、1pxを設定することにしました。
ということで、完成した最終版は下記のような感じになります。(CodePenを使ってみたかったので使ってみました)
AndroidとiPhoneでちょいちょいズレが生じるので、両方で問題がないかを確認するのは大変だなと、改めて思いました。