Kueri media memang bagus, tetapi…
Kueri media sangat bagus, merupakan berkah bagi developer situs yang ingin melakukan sedikit penyesuaian pada stylesheet mereka untuk memberikan pengalaman yang lebih baik bagi pengguna di perangkat dengan berbagai ukuran. Kueri media pada dasarnya memungkinkan Anda menyesuaikan CSS situs, bergantung pada ukuran layar. Sebelum Anda mempelajari artikel ini lebih lanjut, pelajari desain responsif lebih lanjut dan lihat beberapa contoh penggunaan kueri media yang bagus di sini: mediaqueri.es.
Seperti yang ditunjukkan Brad Frost dalam artikel sebelumnya, mengubah tampilan hanya salah satu dari banyak hal yang perlu dipertimbangkan saat mem-build untuk web seluler. Jika satu-satunya hal yang Anda lakukan saat mem-build situs seluler adalah menyesuaikan tata letak dengan kueri media, maka kita akan memiliki situasi berikut:
- Semua perangkat mendapatkan JavaScript, CSS, dan aset (gambar, video) yang sama, sehingga waktu pemuatan menjadi lebih lama dari yang diperlukan.
- Semua perangkat mendapatkan DOM awal yang sama, yang berpotensi memaksa developer menulis CSS yang terlalu rumit.
- Sedikit fleksibilitas untuk menentukan interaksi kustom yang disesuaikan dengan setiap perangkat.
Aplikasi web memerlukan lebih dari kueri media
Jangan salah paham. Saya tidak membenci desain responsif melalui kueri media, dan pasti berpikir bahwa desain responsif memiliki tempat di dunia. Selain itu, beberapa masalah yang disebutkan di atas dapat diselesaikan dengan pendekatan seperti gambar responsif, pemuatan skrip dinamis, dll. Namun, pada titik tertentu, Anda mungkin melakukan terlalu banyak penyesuaian inkremental, dan sebaiknya menayangkan versi yang berbeda.
Seiring meningkatnya kompleksitas UI yang Anda buat, dan Anda cenderung menggunakan web aplikasi satu halaman, Anda perlu melakukan lebih banyak hal untuk menyesuaikan UI untuk setiap jenis perangkat. Artikel ini akan mengajarkan cara melakukan penyesuaian ini dengan sedikit upaya. Pendekatan umum meliputi mengklasifikasikan perangkat pengunjung ke dalam class perangkat yang tepat, dan menayangkan versi yang sesuai ke perangkat tersebut, sekaligus memaksimalkan penggunaan kembali kode antar-versi.
Kelas perangkat apa yang Anda targetkan?
Ada banyak sekali perangkat yang terhubung ke internet, dan hampir semua perangkat tersebut memiliki browser. Kesulitan terletak pada keragamannya: laptop Mac, workstation Windows, iPhone, iPad, ponsel Android dengan input sentuh, roda scroll, keyboard, input suara, perangkat dengan sensitivitas tekanan, smartwatch, pemanggang roti, dan kulkas, serta banyak lagi. Beberapa perangkat ini ada di mana-mana, sementara yang lainnya sangat langka.
Untuk menciptakan pengalaman pengguna yang baik, Anda perlu mengetahui siapa pengguna Anda dan perangkat apa yang mereka gunakan. Jika Anda membuat antarmuka pengguna untuk pengguna desktop dengan mouse dan keyboard, lalu memberikannya kepada pengguna smartphone, antarmuka Anda akan menjadi sumber frustrasi karena dirancang untuk ukuran layar lain, dan modalitas input lain.
Ada dua ujung ekstrem pada spektrum pendekatan:
Buat satu versi yang berfungsi di semua perangkat. Akibatnya, UX akan menurun, karena perangkat yang berbeda memiliki pertimbangan desain yang berbeda.
Build versi untuk setiap perangkat yang ingin Anda dukung. Hal ini akan memakan waktu lama, karena Anda akan mem-build terlalu banyak versi aplikasi. Selain itu, saat smartphone baru berikutnya tiba (yang terjadi kira-kira setiap minggu), Anda akan dipaksa untuk membuat versi lain.
Ada kompromi mendasar di sini: semakin banyak kategori perangkat yang Anda miliki, semakin baik pengalaman pengguna yang dapat Anda berikan, tetapi semakin banyak pekerjaan yang diperlukan untuk mendesain, menerapkan, dan memeliharanya.
Membuat versi terpisah untuk setiap class perangkat yang Anda pilih mungkin merupakan ide yang baik karena alasan performa atau jika versi yang ingin Anda tayangkan ke class perangkat yang berbeda sangat bervariasi. Jika tidak, desain web responsif adalah pendekatan yang sangat wajar.
Solusi potensial
Berikut adalah komprominya: klasifikasikan perangkat ke dalam kategori, dan desain pengalaman terbaik untuk setiap kategori. Kategori yang Anda pilih bergantung pada produk dan target pengguna. Berikut adalah contoh klasifikasi yang mencakup perangkat berkemampuan web populer yang ada saat ini.
- layar kecil + sentuh (sebagian besar ponsel)
- perangkat layar besar + sentuh (sebagian besar tablet)
- perangkat layar besar + keyboard/mouse (sebagian besar desktop/laptop)
Ini hanyalah salah satu dari banyak kemungkinan pengelompokan, tetapi pengelompokan yang sangat masuk akal pada saat penulisan. Tidak ada dalam daftar di atas adalah perangkat seluler tanpa layar sentuh (misalnya, ponsel fitur, beberapa pembaca e-book khusus). Namun, sebagian besar perangkat tersebut telah menginstal software pembaca layar atau navigasi keyboard, yang akan berfungsi dengan baik jika Anda membuat situs dengan mempertimbangkan aksesibilitas.
Contoh aplikasi web khusus faktor bentuk
Ada banyak contoh properti web yang menayangkan versi yang sama sekali berbeda untuk berbagai faktor bentuk. Google Penelusuran melakukan hal ini, begitu juga Facebook. Pertimbangan untuk hal ini mencakup performa (mengambil aset, merender halaman) dan pengalaman pengguna yang lebih umum.
Di dunia aplikasi native, banyak developer memilih untuk menyesuaikan pengalaman mereka dengan class perangkat. Misalnya, Flipboard untuk iPad memiliki UI yang sangat berbeda dibandingkan dengan Flipboard di iPhone. Versi tablet dioptimalkan untuk penggunaan dua tangan dan membalik horizontal, sedangkan versi ponsel ditujukan untuk interaksi satu tangan dan membalik vertikal. Banyak aplikasi iOS lainnya juga menyediakan versi ponsel dan tablet yang sangat berbeda, seperti Things (daftar tugas), dan Showyou (video sosial), yang ditampilkan di bawah:
Pendekatan #1: Deteksi sisi server
Di server, kita memiliki pemahaman yang jauh lebih terbatas tentang perangkat yang kita tangani. Mungkin petunjuk paling berguna yang tersedia adalah string agen pengguna, yang disediakan melalui header User-Agent pada setiap permintaan. Oleh karena itu, pendekatan sniffing UA yang sama akan berfungsi di sini. Faktanya, project DeviceAtlas dan WURFL sudah melakukannya (dan memberikan banyak informasi tambahan tentang perangkat).
Sayangnya, setiap metode ini memiliki tantangannya sendiri. WURFL sangat besar, berisi XML 20 MB, yang berpotensi menimbulkan overhead sisi server yang signifikan untuk setiap permintaan. Ada project yang memisahkan XML karena alasan performa. DeviceAtlas bukan open source, dan memerlukan lisensi berbayar untuk digunakan.
Ada juga alternatif yang lebih sederhana dan gratis, seperti project Detect Mobile Browsers. Kelemahannya, tentu saja, adalah deteksi perangkat pasti akan kurang komprehensif. Selain itu, hanya membedakan antara perangkat seluler dan non-seluler, yang memberikan dukungan tablet terbatas hanya melalui kumpulan tweak ad-hoc.
Pendekatan #2: Deteksi sisi klien
Kita dapat mempelajari banyak hal tentang browser dan perangkat pengguna dengan menggunakan deteksi fitur. Hal utama yang perlu kita tentukan adalah apakah perangkat memiliki kemampuan sentuh, dan apakah layarnya besar atau kecil.
Kita perlu menarik garis di suatu tempat untuk membedakan perangkat sentuh kecil dan besar. Bagaimana dengan kasus ekstrem seperti Galaxy Note 5"? Grafik berikut menunjukkan sekumpulan perangkat Android dan iOS populer yang ditempatkan secara bertumpuk (dengan resolusi layar yang sesuai). Tanda bintang menunjukkan bahwa perangkat hadir atau dapat hadir dalam kepadatan ganda. Meskipun kepadatan piksel dapat digandakan, CSS masih melaporkan ukuran yang sama.
Catatan singkat tentang piksel di CSS: Piksel CSS di web seluler tidak sama dengan piksel layar. Perangkat retina iOS memperkenalkan praktik menggandakan kepadatan piksel (misalnya, iPhone 3GS vs 4, iPad 2 vs 3). UA Safari Seluler retina masih melaporkan lebar perangkat yang sama untuk menghindari kerusakan web. Seperti perangkat lain (misalnya Android) mendapatkan layar resolusi lebih tinggi, mereka melakukan trik lebar perangkat yang sama.
Namun, yang mempersulit keputusan ini adalah pentingnya mempertimbangkan mode potret dan lanskap. Kita tidak ingin memuat ulang halaman atau memuat skrip tambahan setiap kali kita mengorientasikan ulang perangkat, meskipun kita mungkin ingin merender halaman secara berbeda.
Dalam diagram berikut, persegi mewakili dimensi maksimum setiap perangkat, sebagai hasil dari overlay garis batas potret dan lanskap (dan melengkapi persegi):
Dengan menetapkan nilai minimum ke 650px
, kita mengklasifikasikan iPhone, Galaxy Nexus sebagai
smalltouch, dan iPad, Galaxy Tab sebagai "tablet". Dalam hal ini, Galaxy Note
androgynous diklasifikasikan sebagai "ponsel", dan akan mendapatkan tata letak
ponsel.
Jadi, strategi yang wajar mungkin terlihat seperti ini:
if (hasTouch) {
if (isSmall) {
device = PHONE;
} else {
device = TABLET;
}
} else {
device = DESKTOP;
}
Lihat contoh minimal pendekatan deteksi fitur yang sedang berjalan.
Pendekatan alternatif di sini adalah menggunakan sniffing UA untuk mendeteksi jenis
perangkat. Pada dasarnya, Anda membuat serangkaian heuristik dan mencocokkannya dengan
navigator.userAgent
pengguna. Kode semu terlihat seperti
ini:
var ua = navigator.userAgent;
for (var re in RULES) {
if (ua.match(re)) {
device = RULES[re];
return;
}
}
Lihat contoh penerapan pendekatan deteksi UA.
Catatan tentang pemuatan sisi klien
Jika melakukan deteksi UA di server, Anda dapat menentukan CSS, JavaScript, dan DOM yang akan ditayangkan saat mendapatkan permintaan baru. Namun, jika Anda melakukan deteksi sisi klien, situasinya akan lebih kompleks. Anda memiliki beberapa opsi:
- Alihkan ke URL khusus jenis perangkat yang berisi versi untuk jenis perangkat ini.
- Memuat aset khusus jenis perangkat secara dinamis.
Pendekatan pertama bersifat sederhana, yang memerlukan pengalihan seperti
window.location.href = '/tablet'
. Namun, lokasi kini akan memiliki
informasi jenis perangkat ini yang ditambahkan, jadi sebaiknya gunakan
History API untuk membersihkan URL Anda. Sayangnya, pendekatan ini
melibatkan pengalihan, yang dapat lambat, terutama di perangkat
seluler.
Pendekatan kedua ini sedikit lebih kompleks untuk diterapkan. Anda memerlukan
mekanisme untuk memuat CSS dan JS secara dinamis, dan (bergantung pada browser), Anda
mungkin tidak dapat melakukan hal-hal seperti menyesuaikan <meta viewport>
. Selain itu,
karena tidak ada pengalihan, Anda akan terjebak dengan HTML asli yang
ditayangkan. Tentu saja, Anda dapat memanipulasinya dengan JavaScript, tetapi hal ini mungkin
lambat dan/atau tidak elegan, bergantung pada aplikasi Anda.
Menentukan klien atau server
Berikut adalah konsekuensi antara pendekatan tersebut:
Klien pro:
- Lebih siap untuk masa mendatang karena didasarkan pada ukuran/kemampuan layar, bukan UA.
- Tidak perlu terus memperbarui daftar UA.
Server pro:
- Kontrol penuh atas versi yang akan ditayangkan ke perangkat tertentu.
- Performa yang lebih baik: tidak perlu pengalihan klien atau pemuatan dinamis.
Preferensi pribadi saya adalah memulai dengan device.js dan deteksi sisi klien. Seiring perkembangan aplikasi, jika Anda mendapati bahwa pengalihan sisi klien merupakan kelemahan performa yang signifikan, Anda dapat dengan mudah menghapus skrip device.js, dan menerapkan deteksi UA di server.
Memperkenalkan device.js
Device.js adalah titik awal untuk melakukan deteksi perangkat semantik berbasis kueri media tanpa memerlukan konfigurasi sisi server khusus, sehingga menghemat waktu dan upaya yang diperlukan untuk melakukan penguraian string agen pengguna.
Idenya adalah Anda memberikan markup yang mudah digunakan mesin telusur (link
rel=alternate) di bagian atas <head>
yang menunjukkan versi
situs yang ingin Anda berikan.
<link rel="alternate" href="http://foo.com" id="desktop"
media="only screen and (touch-enabled: 0)">
Selanjutnya, Anda dapat melakukan deteksi UA sisi server dan menangani pengalihan versi sendiri, atau menggunakan skrip device.js untuk melakukan pengalihan sisi klien berbasis fitur.
Untuk informasi selengkapnya, lihat halaman project device.js, dan juga aplikasi palsu yang menggunakan device.js untuk pengalihan sisi klien.
Rekomendasi: MVC dengan tampilan khusus faktor bentuk
Sekarang Anda mungkin berpikir bahwa saya meminta Anda untuk mem-build tiga aplikasi yang benar-benar terpisah, satu untuk setiap jenis perangkat. Tidak! Berbagi kode adalah kuncinya.
Semoga Anda telah menggunakan framework seperti MVC, seperti Backbone, Ember, dll. Jika sudah, Anda sudah memahami prinsip pemisahan perhatian, khususnya bahwa UI (lapisan tampilan) harus dipisahkan dari logika (lapisan model). Jika Anda baru mengenalnya, mulailah dengan beberapa referensi tentang MVC, dan MVC dalam JavaScript.
Cerita lintas perangkat cocok dengan framework MVC yang ada. Anda dapat dengan mudah memindahkan tampilan ke file terpisah, membuat tampilan kustom untuk setiap jenis perangkat. Kemudian, Anda dapat menayangkan kode yang sama ke semua perangkat, kecuali lapisan tampilan.
Project Anda mungkin memiliki struktur berikut (tentu saja, Anda bebas memilih struktur yang paling sesuai, bergantung pada aplikasi Anda):
models/ (model bersama) item.js item-collection.js
controllers/ (shared controllers) item-controller.js
versions/ (hal khusus perangkat) tablet/ desktop/ phone/ (kode khusus ponsel) style.css index.html views/ item.js item-list.js
Struktur semacam ini memungkinkan Anda mengontrol sepenuhnya aset yang dimuat setiap versi, karena Anda memiliki HTML, CSS, dan JavaScript kustom untuk setiap perangkat. Hal ini sangat canggih, dan dapat menghasilkan cara pengembangan yang paling ramping dan berperforma tinggi untuk web lintas perangkat, tanpa mengandalkan trik seperti gambar adaptif.
Setelah menjalankan alat build favorit, Anda akan menggabungkan dan meminifikasi semua JavaScript dan CSS menjadi satu file untuk pemuatan yang lebih cepat, dengan HTML produksi yang terlihat seperti berikut (untuk ponsel, menggunakan device.js):
<!doctype html>
<head>
<title>Mobile Web Rocks! (Phone Edition)</title>
<!-- Every version of your webapp should include a list of all
versions. -->
<link rel="alternate" href="http://foo.com" id="desktop"
media="only screen and (touch-enabled: 0)">
<link rel="alternate" href="http://m.foo.com" id="phone"
media="only screen and (max-device-width: 650px)">
<link rel="alternate" href="http://tablet.foo.com" id="tablet"
media="only screen and (min-device-width: 650px)">
<!-- Viewport is very important, since it affects results of media
query matching. -->
<meta name="viewport" content="width=device-width">
<!-- Include device.js in each version for redirection. -->
<script src="device.js"></script>
<link rel="style" href="phone.min.css">
</head>
<body>
<script src="phone.min.js"></script>
</body>
Perhatikan bahwa kueri media (touch-enabled: 0)
bersifat non-standar (hanya
diimplementasikan di Firefox di belakang awalan vendor moz
), tetapi ditangani
dengan benar (berkat Modernizr.touch) oleh device.js.
Penggantian versi
Deteksi perangkat terkadang dapat salah, dan dalam beberapa kasus, pengguna mungkin lebih suka melihat tata letak tablet di ponsel mereka (mungkin mereka menggunakan Galaxy Note), jadi penting untuk memberi pengguna pilihan versi situs mana yang akan digunakan jika mereka ingin menggantinya secara manual.
Pendekatan yang biasa dilakukan adalah dengan memberikan link ke versi desktop dari
versi seluler Anda. Hal ini cukup mudah diterapkan, tetapi device.js mendukung
fungsi ini dengan parameter GET device
.
Penutup
Untuk meringkas, saat membuat UI satu halaman lintas perangkat, yang tidak sesuai dengan dunia desain responsif, lakukan hal berikut:
- Pilih kumpulan class perangkat yang akan didukung, dan kriteria untuk mengklasifikasikan perangkat ke dalam class.
- Build aplikasi MVC Anda dengan pemisahan masalah yang kuat, yang memisahkan tampilan dari codebase lainnya.
- Gunakan device.js untuk melakukan deteksi class perangkat sisi klien.
- Jika sudah siap, paketkan skrip dan stylesheet ke dalam salah satu setiap class perangkat.
- Jika performa pengalihan sisi klien menjadi masalah, tinggalkan device.js dan beralihlah ke deteksi UA sisi server.