Mengelola Interaksi SVG Dengan Properti Acara Pointer

Diterbitkan: 2022-03-10
Ringkasan cepat Mari kita lihat bagaimana membentuk interaktivitas gambar SVG — yaitu, mengontrol bagian mana dari dokumen yang dapat menerima klik, sentuhan, atau ketukan — menggunakan properti pointer-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.

Lihat Pena Amethyst oleh Tiffany Brown (@webinista) di CodePen.

Lihat Pena Amethyst oleh Tiffany Brown (@webinista) di CodePen.

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 .

Lebih banyak setelah melompat! Lanjutkan membaca di bawah ini

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:

  1. Nilai yang membutuhkan elemen agar terlihat; dan
  2. 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.

Lihat Pen Visible vs dicat dalam SVG oleh Tiffany Brown (@webinista) di CodePen.

Lihat Pen Visible vs dicat dalam SVG oleh Tiffany Brown (@webinista) di CodePen.

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 .

Lihat Pena Bagaimana menambahkan pointer-events: semua mempengaruhi interaktivitas oleh Tiffany Brown (@webinista) di CodePen.

Lihat Pena Bagaimana menambahkan pointer-events: semua mempengaruhi interaktivitas oleh Tiffany Brown (@webinista) di CodePen.

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.

Lihat Pena Menambah area klik gambar SVG oleh Tiffany Brown (@webinista) di CodePen.

Lihat Pena Menambah area klik gambar SVG oleh Tiffany Brown (@webinista) di CodePen.

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.

Lihat Pena Menambah area klik gambar SVG oleh Tiffany Brown (@webinista) di CodePen.

Lihat Pena Menambah area klik gambar SVG oleh Tiffany Brown (@webinista) di CodePen.

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.

Lihat Pena Ovxmmy oleh Tiffany Brown (@webinista) di CodePen.

Lihat Pena Ovxmmy oleh Tiffany Brown (@webinista) di CodePen.

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.

Lihat Pen Bagaimana pointer-events: tidak ada yang dapat digunakan dengan SVG dan HTML oleh Tiffany Brown (@webinista) di CodePen.

Lihat Pen Bagaimana pointer-events: tidak ada yang dapat digunakan dengan SVG dan HTML oleh Tiffany Brown (@webinista) di CodePen.

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.