Cara Custom Gaya Form File Upload


Ada beberapa teknik untuk "menyesuaikan" elemen <input type = "file" />. Aku mencoba sebagian besar dari mereka, tapi tidak ada yang cukup baik untuk memiliki di Readerrr (untuk mengimpor feed dengan mengunggah file). Mungkin teknik yang paling buruk adalah di mana elemen input dimasukkan ke dalam wadah (yang meniru tombol), dan masukan mengikuti kursor sehingga saat Anda mengklik di mana saja pada wadah, Anda benar-benar mengeklik masukan. Kedengarannya menarik dan aneh pada saat bersamaan, bukan? Bagaimanapun, itu memiliki beberapa kekurangan yang tidak dapat diterima (kegunaan, sentuhan).

Sebagai hasilnya, saya mencoba googling untuk mendapatkan solusi yang tak terlihat. Setelah itu sepertinya tidak ada yang baru, mata saya tertangkap oleh sebuah komentar di StackOverflow. Itu hanya beberapa suara dan hilang di suatu tempat di tengah halaman, tapi yang terpenting berisi kata ajaib - <label>! Seperti yang mungkin Anda ketahui, menekan label pada dasarnya memicu acara fokus untuk input terikat. Yang menarik adalah, jika itu adalah file input, hasilnya sebagai acara klik, sehingga akan membuka file browser. Ini bagus untuk menyusun solusi semantik:
<input type="file" name="file" id="file" class="inputfile" />
<label for="file">Choose a file</label>
Jadi, menekan salah satu dari kedua elemen ini memberi kita hasil yang sama. Itu berarti bagian yang paling sulit adalah ... dipecahkan! Tidak ada JavaScript, tidak ada solusi kompleks lainnya seperti pelacakan posisi kursor, hanya dua baris ini. Lihat diri mu sendiri:

Sekarang mari kita gaya saja dan membuat ini terlihat seperti tombol normal.

Menyembunyikan <input>
Pertama, kita perlu menyembunyikan bebek jelek itu. Properti CSS seperti display: none atau visibility: hidden tidak akan berhasil. Alasannya adalah: nilai input tidak akan dikirim ke server pada form submit; masukan akan dikecualikan dari urutan tab (Anda ingin situs web Anda diakses, bukan?). Saya membuat kombinasi properti CSS / nilai untuk menyembunyikan masukan secara visual namun tetap terlihat untuk browser:
.inputfile {
 width: 0.1px;
 height: 0.1px;
 opacity: 0;
 overflow: hidden;
 position: absolute;
 z-index: -1;
}
Saya melihat Anda bertanya-tanya mengapa lebar dan tinggi ditetapkan ke 0.1px bukan hanya 0px. Menetapkan nilai properti menjadi nol akhirnya membuang elemen dari pesta tab di beberapa browser. Dan posisi: mutlak menjamin unsur tersebut tidak mengganggu unsur sibling.

Gaya Pada <label>
Karena elemen <label> secara visual adalah tombolnya, Anda dapat menggunakan semua jus CSS kreatif Anda di dalamnya. Saya berpegang pada sesuatu yang sangat sederhana untuk saat ini:
.inputfile + label {
    font-size: 1.25em;
    font-weight: 700;
    color: white;
    background-color: black;
    display: inline-block;
}

.inputfile:focus + label,
.inputfile + label:hover {
    background-color: red;
}
Aksesibilitas
Bagaimana Anda tahu bahwa sebuah elemen di situs web ditekan? Pertama, elemen harus mengkomunikasikan perasaan yang bisa Anda sentuh atau klik di atasnya. Kedua, ikon kursor harus berubah menjadi yang sesuai saat mengarahkan elemen. Yang pertama yang telah kita selesaikan sebelumnya, ayo kita selesaikan yang terakhir, karena label tidak memicu perubahan kursor secara default:
.inputfile + label {
 cursor: pointer; /* "hand" cursor */
}
Navigasi Keyboard
Jika pengguna tidak dapat menavigasi di situs web Anda hanya dengan menggunakan keyboard, Anda melakukan kesalahan. Menyembunyikan masukan itu sendiri dengan cara yang benar adalah satu hal, yang lain menunjukkan kapan elemen difokuskan, yaitu rendering .inputfile: fokus pada label:
.inputfile:focus + label {
 outline: 1px dotted #000;
 outline: -webkit-focus-ring-color auto 5px;
}
-webkit-focus-ring-color auto 5px adalah sedikit trik untuk mendapatkan gambaran garis bawaan terlihat di Chrome, Opera dan Safari. Gaya di garis atas adalah untuk browser yang tidak mengerti -webkit ... expression.

Kemungkinan Sentuh
Jika Anda telah menggunakan FastClick (sebuah perpustakaan untuk menghilangkan jeda tekan 300ms pada perangkat berkemampuan sentuh) dan meminta penambahan markup ekstra pada konten label, tombol tidak akan berfungsi sebagaimana mestinya, kecuali jika Anda menggunakan pointer-events: none, masing-masing:
<label for="file"><strong>Choose a file</strong></label>
.inputfile + label * {
 pointer-events: none;
}
Peningkatan JavaScript
Mungkin dan mudah-mudahan hal terakhir yang hilang adalah menunjukkan apakah file telah dipilih. Masukan file biasanya menunjukkan hal itu, namun dalam kasus kami, input secara visual tersembunyi. Untungnya, ada jalan keluar: peningkatan JavaScript kecil. Teks label menjadi nama file yang dipilih. Jika ada beberapa file yang dipilih, teks akan memberi tahu kami berapa banyak dari mereka yang terpilih.
<input type="file" name="file" id="file" class="inputfile" data-multiple-caption="{count} files selected" multiple />
var inputs = document.querySelectorAll( '.inputfile' );
Array.prototype.forEach.call( inputs, function( input )
{
 var label  = input.nextElementSibling,
  labelVal = label.innerHTML;

 input.addEventListener( 'change', function( e )
 {
  var fileName = '';
  if( this.files && this.files.length > 1 )
   fileName = ( this.getAttribute( 'data-multiple-caption' ) || '' ).replace( '{count}', this.files.length );
  else
   fileName = e.target.value.split( '\\' ).pop();

  if( fileName )
   label.querySelector( 'span' ).innerHTML = fileName;
  else
   label.innerHTML = labelVal;
 });
});
Ada juga versi jQuery dari kode ini yang disajikan di sumber file demo. Pastikan untuk memeriksanya.

Sedikit penjelasan:

  1. Memiliki atribut native [multiple] memungkinkan pengguna untuk memilih lebih dari satu file per upload. Sedangkan [data-multiple-caption] adalah atribut fiktif untuk mengekspresikan pesan jika beberapa file dipilih. Di sini Anda bisa mengatur sebuah pesan khusus. Penggunaan frase {count} bersifat opsional dan fragmennya diganti dengan jumlah file yang dipilih. Alasan saya menggunakan atribut HTML tambahan alih-alih menetapkan kalimat ini sebagai nilai untuk variabel JavaScript adalah karena lebih mudah menyimpan salinannya jika berada di satu tempat.
  2. Atribut HTML [multiple] tidak didukung di IE 9 dan di bawahnya dan juga tidak ada properti file JavaScript. Untuk kasus terakhir, kita hanya mengandalkan nilai. Karena biasanya memiliki nilai format C: \ fakepath \ filename.jpg, split ('\\') .pop () mengekstrak apa yang sebenarnya - nama file.
  3. Yang menarik adalah anda bisa mengimbangi nilai input dengan menekan tombol ESC saat berada di file browser. Ini hanya mungkin di Chrome dan Opera. Oleh karena itu, kami menggunakan labelVal untuk menyimpan nilai default label dan membawanya kembali bila perlu.

Bagaimana jika JavaScript tidak tersedia?
Karena tidak ada cara JavaScript-kurang untuk menunjukkan jika ada file yang dipilih, akan lebih baik mengandalkan tampilan default dari input file demi kegunaan. Yang perlu kita lakukan adalah menambahkan nama kelas .no-js ke elemen <html> lalu gunakan JavaScript dan ganti dengan .js - begitulah cara kita tahu jika JavaScript tersedia.
<html class="no-js">
    <head>
        <!-- remove this if you use Modernizr -->
        <script>(function(e,t,n){var r=e.querySelectorAll("html")[0];r.className=r.className.replace(/(^|\s)no-js(\s|$)/,"$1js$2")})(document,window,0);</script>
    </head>
</html>
Bagian CSS yang sesuai:
.js .inputfile {
    width: 0.1px;
    height: 0.1px;
    opacity: 0;
    overflow: hidden;
    position: absolute;
    z-index: -1;
}

.no-js .inputfile + label {
    display: none;
}
Simak contoh gaya di demo untuk melihat bagaimana gaya elemen input file sesuai kebutuhan anda. Pastikan untuk melihat kode sumber demo dan merasa bebas untuk menggunakan teknik ini dalam proyek Anda. Selamat mengupload!


Password: www.duniadesain.net
Script ini bisa bekerja di ( IE9, Google Chrome 30+, Firefox 27+)

Ikon dalam demo tersebut dibuat oleh Daniel Bruce dari www.flaticon.com dan dilisensikan di bawah CC BY 3.0.
Source: Tympanus

Comments

Popular posts from this blog

Navigasi Button Untuk SlideShow

Transisi untuk Menu Off-Canvas