Ringkasan dasar tentang cara mem-build komponen FAB yang adaptif terhadap warna, responsif, dan dapat diakses.
Dalam postingan ini, saya ingin membagikan pemikiran saya tentang cara mem-build komponen FAB yang adaptif terhadap warna, responsif, dan mudah diakses. Coba demo dan lihat sumbernya.
Jika Anda lebih suka video, berikut versi YouTube dari postingan ini:
Ringkasan
FAB lebih umum digunakan di perangkat seluler daripada desktop, tetapi FAB juga umum digunakan di kedua skenario tersebut. Tindakan utama tetap terlihat, sehingga mudah dan selalu ada. Gaya pengalaman pengguna ini dipopulerkan oleh Material UI dan saran penggunaan serta penempatannya dapat ditemukan di sini.
Elemen dan gaya
HTML untuk kontrol ini melibatkan elemen penampung dan sekumpulan satu atau beberapa tombol. Penampung memosisikan FAB dalam area pandang dan mengelola celah di antara tombol. Tombol dapat berukuran mini atau default, sehingga memberikan beberapa variasi yang bagus antara tindakan utama dan sekunder.
Penampung FAB
Elemen ini dapat berupa <div>
reguler, tetapi mari kita bantu pengguna yang tidak dapat melihat
dan beri tag dengan beberapa atribut yang berguna untuk menjelaskan tujuan dan konten
penampung ini.
Markup FAB
Mulai dengan class .fabs
agar CSS dapat terhubung untuk gaya, lalu tambahkan
role="group"
dan aria-label
sehingga tidak hanya penampung generik, tetapi
juga diberi nama dan tujuan.
<div class="fabs" role="group" aria-label="Floating action buttons">
<!-- buttons will go here -->
</div>
Gaya FAB
Agar FAB mudah digunakan, FAB akan selalu berada dalam area pandang.
Ini adalah kasus penggunaan yang bagus untuk posisi
fixed
. Dalam
posisi area pandang ini, saya memilih untuk menggunakan
inset-block
dan
inset-inline
sehingga
posisi akan melengkapi mode dokumen pengguna, seperti kanan-ke-kiri atau
kiri-ke-kanan. Properti kustom juga digunakan untuk mencegah pengulangan dan memastikan jarak yang sama dari tepi bawah dan samping area pandang:
.fabs {
--_viewport-margin: 2.5vmin;
position: fixed;
z-index: var(--layer-1);
inset-block: auto var(--_viewport-margin);
inset-inline: auto var(--_viewport-margin);
}
Selanjutnya, saya memberikan tampilan penampung
flex
dan mengubah
arah tata letaknya menjadi
column-reverse
.
Tindakan ini akan menumpuk turunan di atas satu sama lain (kolom) dan juga membalikkan
urutan visualnya. Hal ini akan membuat elemen pertama yang dapat difokuskan menjadi elemen bawah, bukan elemen atas, yang akan menjadi tempat fokus biasanya per dokumen HTML. Membalik urutan visual akan menyatukan pengalaman bagi pengguna
yang dapat melihat dan pengguna keyboard, karena gaya visual tindakan utama yang lebih besar daripada
tombol mini menunjukkan kepada pengguna yang dapat melihat bahwa tindakan tersebut adalah tindakan utama, dan
pengguna keyboard akan memfokuskannya sebagai item pertama dalam sumber.
.fabs {
…
display: flex;
flex-direction: column-reverse;
place-items: center;
gap: var(--_viewport-margin);
}
Pemusatan ditangani dengan
place-items
, dan
gap
menambahkan spasi di antara
tombol FAB yang ditempatkan di penampung.
Tombol FAB
Saatnya menata gaya beberapa tombol agar terlihat seperti mengambang di atas semuanya.
FAB Default
Tombol pertama yang akan diberi gaya adalah tombol default. Ini akan berfungsi sebagai dasar untuk semua tombol FAB. Nanti kita akan membuat varian yang mencapai tampilan alternatif sekaligus memodifikasi gaya dasar ini sesedikit mungkin.
Markup FAB
Elemen <button>
adalah pilihan yang tepat. Kita akan memulai dengan ini sebagai dasar
karena dilengkapi dengan pengalaman pengguna mouse, sentuh, dan keyboard yang luar biasa. Aspek
yang paling penting dari markup ini adalah menyembunyikan ikon dari pengguna pembaca layar dengan
aria-hidden="true"
dan menambahkan teks label yang diperlukan ke markup <button>
itu sendiri. Saat menambahkan label dalam kasus ini, saya juga suka menambahkan title
sehingga pengguna mouse
dapat mendapatkan informasi tentang apa yang ingin dikomunikasikan ikon.
<button data-icon="plus" class="fab" title="Add new action" aria-label="Add new action">
<svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">...</svg>
</button>
Gaya FAB
Pertama, mari kita ubah tombol menjadi tombol bulat dengan padding dan bayangan yang kuat, karena ini adalah fitur penentu pertama tombol:
.fab {
--_size: 2rem;
padding: calc(var(--_size) / 2);
border-radius: var(--radius-round);
aspect-ratio: 1;
box-shadow: var(--shadow-4);
}
Selanjutnya, mari kita tambahkan warna. Kita akan menggunakan strategi yang telah kita gunakan dalam Tantangan GUI sebelumnya. Buat kumpulan properti kustom yang diberi nama dengan jelas yang menyimpan warna terang dan gelap secara statis, lalu properti kustom adaptif yang akan ditetapkan ke variabel terang atau gelap, bergantung pada preferensi sistem pengguna untuk warna:
.fab {
…
/* light button and button hover */
--_light-bg: var(--pink-6);
--_light-bg-hover: var(--pink-7);
/* dark button and button hover */
--_dark-bg: var(--pink-4);
--_dark-bg-hover: var(--pink-3);
/* adaptive variables set to light by default */
--_bg: var(--_light-bg);
/* static icon colors set to the adaptive foreground variable */
--_light-fg: white;
--_dark-fg: black;
--_fg: var(--_light-fg);
/* use the adaptive properties on some styles */
background: var(--_bg);
color: var(--_fg);
&:is(:active, :hover, :focus-visible) {
--_bg: var(--_light-bg-hover);
@media (prefers-color-scheme: dark) {
--_bg: var(--_dark-bg-hover);
}
}
/* if users prefers dark, set adaptive props to dark */
@media (prefers-color-scheme: dark) {
--_bg: var(--_dark-bg);
--_fg: var(--_dark-fg);
}
}
Selanjutnya, tambahkan beberapa gaya untuk membantu ikon SVG sesuai dengan ruang.
.fab {
…
& > svg {
inline-size: var(--_size);
block-size: var(--_size);
stroke-width: 3px;
}
}
Terakhir, hapus sorotan ketuk dari tombol karena kita telah menambahkan respons visual kita sendiri untuk interaksi:
.fab {
-webkit-tap-highlight-color: transparent;
}
FAB Mini
Tujuan bagian ini adalah membuat varian untuk tombol FAB. Dengan membuat beberapa FAB lebih kecil dari tindakan default, kita dapat mempromosikan tindakan yang paling sering dilakukan pengguna.
Markup FAB mini
HTML-nya sama dengan FAB, tetapi kita menambahkan class ".mini" untuk memberi CSS hook ke varian.
<button data-icon="heart" class="fab mini" title="Like action" aria-label="Like action">
<svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">...</svg>
</button>
Gaya FAB mini
Berkat penggunaan properti kustom, satu-satunya perubahan yang diperlukan adalah penyesuaian pada
variabel --_size
.
.fab.mini {
--_size: 1.25rem;
}
Aksesibilitas
Bagian terpenting yang perlu diingat untuk aksesibilitas dengan FAB adalah penempatan dalam alur keyboard halaman. Demo ini hanya memiliki FAB, tidak ada yang dapat bersaing dalam hal urutan dan alur keyboard, yang berarti tidak memiliki peluang untuk menunjukkan alur keyboard yang bermakna. Dalam skenario saat ada elemen yang bersaing untuk fokus, sebaiknya pikirkan dengan cermat tentang di bagian mana dalam alur tersebut pengguna harus memasuki alur tombol FAB.
Setelah pengguna memfokuskan ke penampung FAB, kita telah menambahkan
role="group"
dan aria-label="floating action buttons"
yang memberi tahu pengguna pembaca
layar tentang konten yang telah mereka fokuskan. Secara strategis, saya telah
menempatkan FAB default terlebih dahulu, sehingga pengguna menemukan tindakan utama terlebih dahulu. Kemudian,
saya menggunakan flex-direction: column-reverse;
untuk secara visual mengurutkan tombol utama
di bagian bawah, dekat dengan jari pengguna untuk memudahkan akses. Ini adalah pencapaian yang bagus
karena tombol default terlihat jelas secara visual dan juga pertama bagi pengguna
keyboard, sehingga memberi mereka pengalaman yang sangat mirip.
Terakhir, jangan lupa untuk menyembunyikan ikon dari pengguna pembaca layar dan pastikan Anda
memberi mereka label untuk tombol agar tidak menjadi misteri. Hal ini telah
dilakukan di HTML dengan aria-hidden="true"
di <svg>
dan
aria-label="Some action"
di <button>
.
Animasi
Berbagai jenis animasi dapat ditambahkan untuk meningkatkan pengalaman pengguna. Seperti dalam
Tantangan GUI lainnya, kita akan menyiapkan beberapa properti kustom untuk menyimpan
intent pengalaman gerakan yang dikurangi dan pengalaman gerakan penuh. Secara default,
gaya akan mengasumsikan bahwa pengguna ingin mengurangi gerakan, lalu menggunakan
kueri media prefers-reduced-motion
, menukar nilai transisi ke gerakan penuh.
Strategi pengurangan gerakan dengan properti kustom
Tiga properti kustom dibuat dalam CSS berikut: --_motion-reduced
,
--_motion-ok
, dan --_transition
. Dua yang pertama menyimpan transisi yang sesuai
berdasarkan preferensi pengguna, dan variabel terakhir --_transition
akan ditetapkan
ke --_motion-reduced
atau --_motion-ok
.
.fab {
/* box-shadow and background-color can safely be transitioned for reduced motion users */
--_motion-reduced:
box-shadow .2s var(--ease-3),
background-color .3s var(--ease-3);
/* add transform and outline-offset for users ok with motion */
--_motion-ok:
var(--_motion-reduced),
transform .2s var(--ease-3),
outline-offset 145ms var(--ease-2);
/* default the transition styles to reduced motion */
--_transition: var(--_motion-reduced);
/* set the transition to our adaptive transition custom property*/
transition: var(--_transition);
/* if motion is ok, update the adaptive prop to the respective transition prop */
@media (prefers-reduced-motion: no-preference) {
--_transition: var(--_motion-ok);
}
}
Dengan menerapkan hal di atas, perubahan pada box-shadow
, background-color
,
transform
, dan outline-offset
dapat ditransisikan, sehingga memberi pengguna masukan UI
yang bagus bahwa interaksi mereka telah diterima.
Selanjutnya, tambahkan sedikit lebih banyak gaya ke status :active
dengan menyesuaikan
translateY
sedikit, ini akan memberikan efek tekan yang bagus pada tombol:
.fab {
…
&:active {
@media (prefers-reduced-motion: no-preference) {
transform: translateY(2%);
}
}
}
Terakhir, transisikan perubahan apa pun pada ikon SVG di tombol:
.fab {
…
&[data-icon="plus"]:hover > svg {
transform: rotateZ(.25turn);
}
& > svg {
@media (prefers-reduced-motion: no-preference) {
will-change: transform;
transition: transform .5s var(--ease-squish-3);
}
}
}
Kesimpulan
Setelah Anda tahu cara saya melakukannya, bagaimana Anda melakukannya‽ 🙂
Mari kita diversifikasi pendekatan dan pelajari semua cara untuk mem-build di web.
Buat demo, tweet link-nya, dan saya akan menambahkannya ke bagian remix komunitas di bawah.
Remix komunitas
Belum ada apa-apa di sini.
Resource
- Kode sumber di GitHub