Cara Membangun Modal Popup JavaScript Dari Awal



Dalam tutorial ini kita akan belajar bagaimana membangun JavaScript popup modals  (popup windows) tanpa menggunakan framework seperti Bootstrap, atau library pihak ketiga. Kita akan membangun semuanya dari awal, memberikan kita kendali penuh atas cara kerjanya dan penampilannya.

Inilah demo yang akan kami buat:






Pertama kita akan membuat modal. Untuk melakukan ini, kita akan menambahkan class .modal dan ID unik ke container. Selanjutnya kita akan menentukan dialog dengan menetapkan elemen .modal-dialog sebagai child langsung dari .modal. Dialog akan menampung konten modal. Ini bisa berupa segala jenis konten seperti teks, gambar, lightbox, notifikasi / peringatan pengguna, dll.

    “Sebuah Popup (atau modal) adalah elemen UI kecil yang akan muncul di foreground situs web, biasanya dipicu sebagai permintaan bagi pengguna untuk melakukan sesuatu” - Dayat eMJe

Untuk membuka modal, kita perlu elemen apa pun dengan atribut data-open (biasanya sebuah button). Nilai atribut ini harus menjadi ID dari modal yang diinginkan.

Secara default, modal akan ditutup jika kita mengklik di luar batasnya atau ketika tombol Esc ditekan. Tapi kita juga bisa menutupnya jika kita mengklik elemen apa saja dengan atribut data-close (biasanya sebuah button).

Awalnya modal akan muncul / menghilang dengan efek fade. Tetapi kita memiliki kemampuan untuk menyesuaikan efek animasi dari dialog melalui atribut data-animation. Nilai atribut ini yang harus ditambahkan ke .modal dapat berupa salah satu dari nilai berikut:

  • slideInOutDown
  • slideInOutTop
  • slideInOutLeft
  • slideInOutRight
  • zoomInOut
  • rotateInOutDown
  • mixInAnimations

Kita akan melihat lebih dekat pada nilai-nilai ini di bagian mendatang.

Untuk saat ini, mari kenali markup yang dibutuhkan untuk mewakili satu modal:

1:  <button type="button" class="open-modal" data-open="modal1">...</button>  
2:  <div class="modal" id="modal1">  
3:   <div class="modal-dialog">  
4:    <header class="modal-header">  
5:     ...  
6:     <button class="close-modal" aria-label="close modal" data-close>✕</button>  
7:    </header>  
8:    <section class="modal-content">...</section>  
9:    <footer class="modal-footer">...</footer>  
10:   </div>  
11:  </div>  



Dengan markup yang siap, kita akan menyiapkan beberapa variabel CSS dan mengatur ulang style:

1:  :root {  
2:   --lightgray: #efefef;  
3:   --blue: steelblue;  
4:   --white: #fff;  
5:   --black: rgba(0, 0, 0, 0.8);  
6:   --bounceEasing: cubic-bezier(0.51, 0.92, 0.24, 1.15);  
7:  }  
8:  * {  
9:   padding: 0;  
10:   margin: 0;  
11:  }  
12:  button {  
13:   cursor: pointer;  
14:   background: transparent;  
15:   border: none;  
16:   outline: none;  
17:   font-size: inherit;  
18:  }  


Selanjutnya, kita akan memusatkan konten halaman secara horizontal dan vertikal. Plus, kita akan memberikan beberapa styling pada button yang bertanggung jawab untuk membuka modal:

1:  /*CUSTOM VARIABLES HERE*/  
2:  body {  
3:   display: flex;  
4:   align-items: center;  
5:   justify-content: center;  
6:   height: 100vh;  
7:   font: 16px/1.5 sans-serif;  
8:  }  
9:  .btn-group {  
10:   text-align: center;  
11:  }  
12:  .open-modal {  
13:   font-weight: bold;  
14:   background: var(--blue);  
15:   color: var(--white);  
16:   padding: .75rem 1.75rem;  
17:   margin-bottom: 1rem;  
18:   border-radius: 5px;  
19:  }  





Pada titik ini kita akan memusatkan perhatian pada modal styles.

Setiap modal akan memiliki karakteristik sebagai berikut:

  • Ini akan menjadi full-screen dengan fixed position. Yang mengatakan, itu akan terlihat seperti overlay yang menutupi lebar dan tinggi seluruh window.
  • Ini akan memiliki warna background gelap.
  • Ini akan disembunyikan secara default.
  • Dialog akan dipusatkan secara horizontal dan vertikal.

1:  /*CUSTOM VARIABLES HERE*/  
2:  .modal {   
3:   position: fixed;  
4:   top: 0;  
5:   left: 0;  
6:   right: 0;  
7:   bottom: 0;  
8:   display: flex;  
9:   align-items: center;  
10:   justify-content: center;  
11:   padding: 1rem;  
12:   background: var(--black);  
13:   cursor: pointer;  
14:   visibility: hidden;  
15:   opacity: 0;  
16:   tran  
17:  }   


Dialog akan memiliki lebar maksimum dan tinggi maksimum. Tingginya akan 80% dari tinggi window. Jika ketinggian melebihi nilai itu, vertical scrollbar akan muncul:

1:  /*CUSTOM VARIABLES HERE*/  
2:  .modal-dialog {  
3:   position: relative;  
4:   max-width: 800px;  
5:   max-height: 80vh;  
6:   border-radius: 5px;  
7:   background: var(--white);  
8:   overflow: auto;  
9:   cursor: default;  
10:  }  


Sebagai hal terakhir, kita akan mendefinisikan beberapa style langsung untuk bagian konten individual:

1:  /*CUSTOM VARIABLES HERE*/  
2:  .modal-dialog > * {  
3:   padding: 1rem;  
4:  }  
5:  .modal-header,  
6:  .modal-footer {  
7:   background: var(--lightgray);  
8:  }  
9:  .modal-header {  
10:   display: flex;  
11:   align-items: center;  
12:   justify-content: space-between;  
13:  }  
14:  .modal-header .modal-close {  
15:   font-size: 1.5rem;  
16:  }  
17:  .modal p + p {  
18:   margin-top: 1rem;  
19:  }  







Sebuah halaman dapat memiliki lebih dari satu modal. Tetapi seperti yang sudah dibahas sebelumnya, semua modalnya pada awalnya akan disembunyikan.

Open Modal

Demikian pula, halaman dapat memiliki lebih dari satu open triggers (elemen dengan atribut data-open). Setiap kali trigger diklik, modal terkait akan menjadi terlihat dengan animasi fade-in. Ingat nilai atribut data-open harus cocok dengan ID modal.

Inilah script yang mengungkapkan modal:

1:  const openEls = document.querySelectorAll("[data-open]");  
2:  const isVisible = "is-visible";  
3:  for(const el of openEls) {  
4:   el.addEventListener("click", function() {  
5:    const modalId = this.dataset.open;  
6:    document.getElementById(modalId).classList.add(isVisible);  
7:   });  
8:  }  


Dan CSS classes yang relevan:

1:  .modal {  
2:   visibility: hidden;  
3:   opacity: 0;  
4:   transition: all 0.35s ease-in;  
5:  }  
6:  .modal.is-visible {  
7:   visibility: visible;  
8:   opacity: 1;  
9:  }  


Close Modal

Dengan implementasi kita, hanya satu modal yang dapat muncul pada satu waktu (kode ini tidak mendukung mod yang bersarang). Seperti disebutkan dalam bagian markup di atas, ada tiga metode yang tersedia untuk menyembunyikannya dengan efek fade-out.

Mari kita rekap.

Pertama dengan mengklik elemen [data-close] khusus yang terletak di dalam modal:

1:  const closeEls = document.querySelectorAll("[data-close]");  
2:  const isVisible = "is-visible";  
3:  for (const el of closeEls) {  
4:   el.addEventListener("click", function() {  
5:    this.parentElement.parentElement.parentElement.classList.remove(isVisible);  
6:   });  
7:  }  


Kedua dengan mengklik segala sesuatu di luar modal:

1:  const isVisible = "is-visible";  
2:  document.addEventListener("click", e => {  
3:   if (e.target == document.querySelector(".modal.is-visible")) {  
4:    document.querySelector(".modal.is-visible").classList.remove(isVisible);  
5:   }  
6:  });  


Dalam hal ini modal (overlay) berperilaku sebagai close button raksasa. Untuk alasan ini kita berikan kursor: pointer.

Terakhir dengan menekan tombol Esc:

1:  const isVisible = "is-visible";  
2:  document.addEventListener("keyup", e => {  
3:   if (e.key == "Escape" && document.querySelector(".modal.is-visible")) {  
4:    document.querySelector(".modal.is-visible").classList.remove(isVisible);  
5:   }  
6:  });  

Sekarang cobalah lihat apa yang telah kita buat sejauh ini:




Modal terlihat cukup bagus! Perhatikan bahwa setiap kali kita mengklik open trigger,, hanya modal yang sesuai yang dimuat.

Mari selangkah lebih maju dan kaji beberapa ide untuk menghidupkan dialognya.



Seperti yang kita katakan sebelumnya, perilaku default dari modal adalah fade-in dan fade-out. Tetapi ada opsi untuk menyesuaikan efek animasi dari popup.

Saya sudah membuat banyak efek animasi yang dapat Anda gunakan sebagai alternatif untuk efek fade. Untuk melakukan ini, cukup kirimkan atribut data-animation = "yourDesiredAnimation" ke .modal.

Misalnya, jika Anda ingin dialog muncul dengan animasi slide dari kiri ke kanan, Anda memerlukan efek slideInOutLeft.

Behind the scenes, ada dua aturan yang menyelesaikan animasi yang diinginkan ini:

1:  /*CUSTOM VARIABLES HERE*/  
2:  [data-animation="slideInOutLeft"] .modal-dialog {  
3:   opacity: 0;  
4:   transform: translateX(-100%);  
5:   transition: all 0.5s var(--bounceEasing);  
6:  }  
7:  [data-animation="slideInOutLeft"].is-visible .modal-dialog {  
8:   opacity: 1;  
9:   transform: none;  
10:   transition-delay: 0.2s;  
11:  }  


Periksa modal dengan jenis animasi di sini:



Anda dapat memeriksa sisa animasi dengan melihat tab CSS dari proyek demo final. Bergantung pada kerumitan animasi, saya telah menggunakan transisi atau animasi CSS untuk membangunnya.

Saya juga memanfaatkan fungsi cubic-bezier () untuk mengatur fungsi pengaturan waktu untuk semua transisi. Jika Anda tidak menyukai efek bouncing yang menghasilkan, jangan ragu untuk mengubahnya menjadi sesuatu yang lebih lancar melalui variabel --bounceEasing CSS.

Lihat demo final dengan semua efek animasi di sini:



Kesimpulan

Itu dia, teman-teman! Selama tutorial ini kita belajar bagaimana membangun dialog modal animasi khusus tanpa bergantung pada framework front-end.

Saya harap Anda menikmati hasil akhir dan membangunnya membantu menyegarkan keterampilan front-end Anda.

Ingatlah bahwa kita belum mempertimbangkan aksesibilitas, jadi jika Anda ingin meningkatkan demo ini, itu bisa menjadi langkah selanjutnya.

Terima kasih sudah membaca! See You Next Time :)