Mengelola Interaksi SVG Dengan Properti Acara Pointer
Diterbitkan: 2022-03-10pointer-events
.Coba klik atau tap gambar SVG di bawah ini. Jika Anda meletakkan penunjuk Anda di tempat yang tepat (jalur yang diarsir) maka Anda harus membuka beranda Smashing Magazine di tab browser baru. Jika Anda mencoba mengklik beberapa ruang putih, Anda mungkin benar-benar bingung.
Ini adalah dilema yang saya hadapi selama proyek baru-baru ini yang menyertakan tautan dalam gambar SVG. Terkadang ketika saya mengklik gambar, tautannya berfungsi. Lain kali tidak. Membingungkan, bukan?
Saya beralih ke spesifikasi SVG untuk mempelajari lebih lanjut tentang apa yang mungkin terjadi dan apakah SVG menawarkan perbaikan. Jawabannya: pointer-events
.
Jangan bingung dengan peristiwa penunjuk DOM ( D ocument O bject M odel), peristiwa pointer-events
adalah properti CSS dan atribut elemen SVG. Dengannya, kita dapat mengatur bagian mana dari dokumen atau elemen SVG yang dapat menerima peristiwa dari perangkat penunjuk seperti mouse, trackpad, atau jari.
Catatan tentang terminologi: "peristiwa penunjuk" juga merupakan nama fitur platform web agnostik perangkat untuk input pengguna. Namun, dalam artikel ini — dan untuk tujuan properti pointer-events
— frasa "pointer events" juga menyertakan mouse dan event touch.
Di Luar Kotak: “Model Bentuk” SVG
Menggunakan CSS dengan HTML memaksakan model tata letak kotak pada HTML. Dalam model tata letak kotak, setiap elemen menghasilkan persegi panjang di sekitar isinya. Persegi panjang itu mungkin inline, inline-level, atom inline-level, atau blok, tapi itu masih persegi panjang dengan empat sudut siku-siku dan empat tepi. Saat kita menambahkan link atau event listener ke elemen, area interaktif cocok dengan dimensi persegi panjang.
Catatan : Menambahkan clip-path
ke elemen interaktif akan mengubah batas interaktifnya. Dengan kata lain, jika Anda menambahkan clip-path
heksagonal ke a
, hanya titik di dalam jalur kliping yang dapat diklik. Demikian pula, menambahkan transformasi miring akan mengubah persegi panjang menjadi belah ketupat.
SVG tidak memiliki model tata letak kotak. Anda lihat, ketika dokumen SVG ditampung oleh dokumen HTML, di dalam tata letak CSS, elemen root SVG mengikuti model tata letak kotak. Elemen anaknya tidak. Akibatnya, sebagian besar properti terkait tata letak CSS tidak berlaku untuk SVG.
Jadi sebagai gantinya, SVG memiliki apa yang saya sebut 'model bentuk'. Saat kita menambahkan link atau event listener ke dokumen atau elemen SVG, area interaktif tidak harus berbentuk persegi panjang. Elemen SVG memang memiliki kotak pembatas. Kotak pembatas didefinisikan sebagai: persegi panjang paling pas yang disejajarkan dengan sumbu sistem koordinat pengguna elemen tersebut yang sepenuhnya melingkupinya dan turunannya.
Namun awalnya, bagian mana dari dokumen SVG yang interaktif bergantung pada bagian mana yang terlihat dan/atau dicat .
Dilukis vs. Elemen Terlihat
Elemen SVG dapat "diisi" tetapi juga dapat "dibelai". Isi mengacu pada interior suatu bentuk. Stroke mengacu pada garis besarnya.
Bersama-sama, "isi" dan "goresan" adalah operasi pengecatan yang merender elemen ke layar atau halaman (juga dikenal sebagai kanvas ). Ketika kita berbicara tentang elemen yang dilukis , yang kita maksud adalah elemen tersebut memiliki isian dan/atau goresan. Biasanya, ini berarti elemen juga terlihat.
Namun, elemen SVG dapat dicat tanpa terlihat. Hal ini dapat terjadi jika nilai atribut yang visible
atau properti CSS hidden
atau saat display
none
. Unsur itu ada dan menempati ruang teoretis. Kami hanya tidak dapat melihatnya (dan teknologi bantu mungkin tidak mendeteksinya).
Mungkin yang lebih membingungkan, sebuah elemen juga bisa terlihat — yaitu, memiliki nilai visibility
yang dihitung dari visible
— tanpa dicat. Ini terjadi ketika elemen kekurangan stroke dan fill.
Catatan : Nilai warna dengan transparansi alfa (misalnya rgba(0,0,0,0)
) tidak mempengaruhi apakah suatu elemen dicat atau terlihat. Dengan kata lain, jika sebuah elemen memiliki isian atau goresan transparan alfa, elemen tersebut akan dicat meskipun tidak dapat dilihat.
Mengetahui kapan suatu elemen dilukis, terlihat, atau tidak keduanya sangat penting untuk memahami dampak dari setiap nilai pointer-events
.
Semua Atau Tidak Ada Atau Sesuatu Di Antara: Nilai
pointer-events
adalah properti CSS dan atribut elemen SVG. Nilai awalnya adalah auto
, yang berarti bahwa hanya bagian yang dicat dan terlihat yang akan menerima peristiwa penunjuk. Sebagian besar nilai lainnya dapat dibagi menjadi dua kelompok:
- Nilai yang membutuhkan elemen agar terlihat; dan
- Nilai yang tidak.
painted
, fill
, stroke
, dan all
termasuk dalam kategori yang terakhir. Rekan mereka yang bergantung pada visibilitas — visiblePainted
, visibleFill
, visibleStroke
, dan visible
— termasuk dalam yang pertama.
Spesifikasi SVG 2.0 juga mendefinisikan nilai bounding-box
. Ketika nilai pointer-events
adalah bounding-box
, area persegi panjang di sekitar elemen juga dapat menerima event pointer. Pada tulisan ini, hanya Chrome 65+ yang mendukung nilai bounding-box
.
none
juga merupakan nilai yang valid. Ini mencegah elemen dan anak-anaknya dari menerima acara penunjuk apa pun. Properti CSS pointer-events
dapat digunakan dengan elemen HTML juga. Tetapi ketika digunakan dengan HTML, hanya auto
dan none
ada nilai yang valid.
Karena nilai pointer-events
lebih baik ditunjukkan daripada dijelaskan, mari kita lihat beberapa demo.
Di sini kita memiliki lingkaran dengan isian dan goresan yang diterapkan. Itu dicat dan terlihat . Seluruh lingkaran dapat menerima peristiwa penunjuk, tetapi area di luar lingkaran tidak bisa.
Nonaktifkan isian, sehingga nilainya none
. Sekarang jika Anda mencoba mengarahkan, mengeklik, atau mengetuk bagian dalam lingkaran, tidak ada yang terjadi. Tetapi jika Anda melakukan hal yang sama untuk area goresan, kejadian penunjuk masih dikirim. Mengubah nilai fill
menjadi none
berarti area ini terlihat , tetapi tidak dicat .
Mari kita membuat perubahan kecil pada markup kita. Kami akan menambahkan pointer-events="visible"
ke elemen circle
kami, sambil menjaga fill=none
.
Sekarang area yang tidak dicat yang dikelilingi oleh stroke dapat menerima event pointer.
Menambah Area yang Dapat Diklik dari Gambar SVG
Mari kembali ke gambaran dari awal artikel ini. "Kecubung" kami adalah elemen path
, berlawanan dengan sekelompok poligon yang masing-masing memiliki stroke
dan fill
. Itu berarti kita tidak bisa hanya menambahkan pointer-events="all"
dan menyebutnya sehari.
Sebagai gantinya, kita perlu menambah area klik. Mari gunakan apa yang kita ketahui tentang elemen yang dicat dan terlihat. Pada contoh di bawah ini, saya telah menambahkan persegi panjang ke markup gambar kita.
Meskipun persegi panjang ini tidak terlihat, secara teknis masih terlihat (yaitu visibility: visible
). Kurangnya isian, bagaimanapun, berarti tidak dicat . Gambar kita terlihat sama. Memang masih berfungsi sama — mengklik spasi tetap tidak memicu operasi navigasi. Kita masih perlu menambahkan atribut pointer-events
ke elemen a
kita. Menggunakan nilai yang visible
atau all
akan berfungsi di sini.
Sekarang seluruh gambar dapat menerima acara penunjuk.
Menggunakan bounding-box
akan menghilangkan kebutuhan akan elemen phantom. Semua titik di dalam kotak pembatas akan menerima peristiwa penunjuk, termasuk ruang putih yang diapit oleh jalur. Tetapi sekali lagi: pointer-events="bounding-box"
tidak didukung secara luas. Sampai itu, kita bisa menggunakan elemen yang tidak dicat.
Menggunakan pointer-events
Saat Mencampur SVG Dan HTML
Kasus lain di mana pointer-events
dapat membantu: menggunakan SVG di dalam tombol HTML.
Di sebagian besar browser — Firefox dan Internet Explorer 11 adalah pengecualian di sini — nilai event.target
akan menjadi elemen SVG alih-alih tombol HTML kami. Mari tambahkan pointer-events="none"
ke tag SVG pembuka kita.
Sekarang ketika pengguna mengklik atau mengetuk tombol kami, event.target
akan merujuk ke button
kami.
Mereka yang berpengalaman dalam DOM dan JavaScript akan memperhatikan bahwa menggunakan kata kunci function
alih-alih fungsi panah dan this
alih-alih event.target
memperbaiki masalah ini. Namun, menggunakan pointer-events="none"
(atau pointer-events: none;
di CSS Anda), berarti Anda tidak perlu memasukkan kekhasan JavaScript tertentu ke memori.
Kesimpulan
SVG mendukung jenis interaktivitas yang sama seperti yang biasa kita lakukan dengan HTML. Kita dapat menggunakannya untuk membuat bagan yang merespons klik atau ketukan. Kita dapat membuat area tertaut yang tidak mematuhi model kotak CSS dan HTML. Dan dengan penambahan pointer-events
, kami dapat meningkatkan cara dokumen SVG kami berperilaku dalam menanggapi interaksi pengguna.
Dukungan browser untuk pointer-events
SVG sangat kuat. Setiap browser yang mendukung SVG mendukung properti untuk dokumen dan elemen SVG. Saat digunakan dengan elemen HTML, dukungannya sedikit kurang kuat. Itu tidak tersedia di Internet Explorer 10 atau pendahulunya, atau versi Opera Mini apa pun.
Kami baru saja menggores permukaan pointer-events
di bagian ini. Untuk perawatan teknis yang lebih mendalam, baca Spesifikasi SVG. MDN (Mozilla Developer Network) Web Docs menawarkan lebih banyak dokumentasi ramah pengembang web untuk pointer-events
, lengkap dengan contoh.