Menu yang terbuka saat tombolnya ditekan, jawaban FAQ yang muncul satu per satu, dan panel yang bisa ditutup memakai satu pola yang sama: konten ada di dokumen, tetapi visibilitasnya diatur saat halaman berjalan. Kini kita mengatur elemen mana yang tampil. Chapter ini membandingkan tiga cara menyembunyikan konten, menyoroti dampaknya bagi aksesibilitas, lalu merangkainya menjadi panel FAQ.

Tiga Cara Menyembunyikan Konten #

Ada tiga jalur yang umum dipakai, dan ketiganya bekerja dari lapisan yang berbeda:

CaraCara kerjaCatatan pemakaian
Atribut hiddenStatus tersimpan pada elemen; browser berhenti merendernyaDianjurkan sebagai status bawaan HTML
Class + display: noneJS menambah atau menghapus class; CSS menentukan tampilannyaDianjurkan saat transisi CSS ikut diatur
style.display langsungJS menulis gaya inline pada elemenKurang dianjurkan; gaya bercampur dengan skrip

Ketiga jalur menghasilkan tampilan yang mirip, tetapi semantik dan pemeliharaannya berbeda.

Atribut hidden dan Properti el.hidden #

Atribut hidden adalah boolean global attribute: kehadirannya menyatakan elemen tidak relevan untuk kondisi saat ini, dan browser meresponsnya dengan tidak merender elemen tersebut. Dari JavaScript, atribut ini dicerminkan oleh properti hidden bertipe boolean, sehingga bolak-balik nilainya cukup ditulis lewat penugasan:

javascript Mengalihkan atribut hidden lewat properti
jawaban.hidden = true;  // sembunyikan elemen
jawaban.hidden = false; // tampilkan kembali

Statusnya juga semantik: kondisi “tersembunyi” tersimpan pada elemen, bukan pada nama class. Elemen yang beratribut hidden juga dikeluarkan dari accessibility tree — pembaca layar tidak membacanya dan elemen tersebut tidak dapat menerima fokus keyboard — sehingga pembaca layar dan pengguna keyboard mendapat pengalaman yang konsisten.

Class dengan display: none #

Jalur kedua membagi tugas: JavaScript hanya menambah atau menghapus class, sedangkan wujud tersembunyinya ditentukan CSS. Pola ini memakai classList dari chapter Mengubah Class Elemen:

javascript Toggle class tersembunyi
panel.classList.toggle("tersembunyi");
css Definisi class di file CSS
.tersembunyi {
  display: none;
}

Properti display: none mengeluarkan elemen dari tata letak: ruangnya ikut hilang, seolah elemen tidak pernah ada. Bila ruang perlu dipertahankan, CSS menyediakan visibility: hidden yang menyembunyikan tanpa menggeser elemen lain. Jalur class menjadi pilihan tepat ketika perpindahan ingin dihaluskan dengan transisi CSS.

style.display Langsung dari JavaScript #

Jalur ketiga menulis gaya inline langsung dari skrip:

javascript Mengalihkan style.display langsung
panel.style.display = "none"; // sembunyikan
panel.style.display = "";     // kembalikan sesuai aturan CSS

Cara ini berfungsi, tetapi kurang dianjurkan untuk halaman sungguhan. Gaya inline yang ditulis JavaScript menimpa aturan CSS dari stylesheet, sehingga sumber kebenaran tampilan terpecah; menghapus nilai ("") mengembalikan kendali ke stylesheet. Simpan jalur ini untuk eksperimen cepat.

Tombol Pemicu dan aria-expanded #

Tombol pemicu juga perlu berbicara tentang kondisi panelnya. Atribut ARIA aria-expanded diletakkan pada tombol dengan nilai true atau false, dan pembaca layar mengumumkan status tersebut sebagai “dibentangkan” atau “diciutkan”. Perbarui nilainya di tempat yang sama dengan perubahan visibilitasnya, sebagaimana contoh berikut.

Kapan Elemen details Lebih Tepat #

Bila konten yang dibentangkan-diciutkan bersifat sederhana, HTML menyediakan pasangan details dan summary yang menangani seluruh mekanisme tersebut tanpa satu baris JavaScript pun: browser mengatur klik dan statusnya sendiri. Gunakan details untuk pengungkapan murni seperti jawaban FAQ tunggal, dan pilih JavaScript bila perilakunya lebih khas. Section Interactive Elements membahasnya tuntas; di sini kita buat versi JavaScript-nya untuk melatih pola event dan visibilitas.

Contoh: Panel FAQ dengan hidden #

Kita gabungkan hidden dan aria-expanded dalam satu panel FAQ. File faq-toggle.html menyediakan struktur dan gaya:

html faq-toggle.html
<!doctype html>
<html lang="id">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>FAQ Toko Kelontong Budi</title>
  <script src="faq-toggle.js" defer></script>
  <style>
    .faq {
      max-width: 480px;
    }
    #jawaban-faq {
      border-left: 3px solid #1a6b54;
      padding-left: 12px;
    }
  </style>
</head>
<body>
  <h1>Pertanyaan yang Sering Diajukan</h1>
  <section class="faq">
    <h2>Berapa lama pengiriman pesanan?</h2>
    <button id="tombol-faq" type="button" aria-expanded="false" aria-controls="jawaban-faq">
      Lihat jawaban
    </button>
    <p id="jawaban-faq" hidden>
      Pesanan diantar dalam satu sampai dua hari kerja ke alamat seperti Jl. Melati No. 10.
    </p>
  </section>
</body>
</html>

Skripnya berada di file faq-toggle.js:

javascript faq-toggle.js
const tombol = document.querySelector("#tombol-faq");
const jawaban = document.querySelector("#jawaban-faq");

tombol.addEventListener("click", function () {
  if (jawaban.hidden) {
    jawaban.hidden = false;
    tombol.setAttribute("aria-expanded", "true");
  } else {
    jawaban.hidden = true;
    tombol.setAttribute("aria-expanded", "false");
  }
});

Output yang Dihasilkan:

text
Saat halaman baru dibuka:
  - Hanya pertanyaan dan tombol "Lihat jawaban" yang tampil
  - Paragraf jawaban tidak dirender karena atribut hidden
Saat tombol ditekan:
  - Paragraf jawaban tampil dengan garis hijau di sisi kirinya
Saat tombol ditekan lagi:
  - Paragraf jawaban tersembunyi kembali

Mari kita bedah kedua file itu:

  1. Baris 22-24 HTML (<button ...>): tombol pemicu membawa aria-expanded="false" sebagai status awal dan aria-controls="jawaban-faq" yang menunjuk id panelnya.
  2. Baris 25-27 HTML (<p id="jawaban-faq" hidden>): jawaban tersembunyi sejak awal, tanpa perlu satu baris CSS pun.
  3. Baris 1-2 JS (querySelector): kode memegang referensi tombol dan paragraf jawaban.
  4. Baris 4-12 JS (listener klik): if memilih salah satu dari dua cabang. Bila jawaban.hidden bernilai true, paragraf ditampilkan dan aria-expanded diubah ke true lewat setAttribute; bila tidak, paragraf disembunyikan dan aria-expanded kembali ke false.

Pola ini — event, visibilitas, dan pembaruan status tombol — adalah fondasi menu, tab, dan dialog. Chapter berikutnya memindahkannya ke ranah formulir: menyaring isian sebelum data dikirim.

Referensi resmi untuk pendalaman:

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

faq-toggle.html

Unduh berkas
html
<!doctype html>
<html lang="id">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>FAQ Toko Kelontong Budi</title>
  <script src="faq-toggle.js" defer></script>
  <style>
    .faq {
      max-width: 480px;
    }
    #jawaban-faq {
      border-left: 3px solid #1a6b54;
      padding-left: 12px;
    }
  </style>
</head>
<body>
  <h1>Pertanyaan yang Sering Diajukan</h1>
  <section class="faq">
    <h2>Berapa lama pengiriman pesanan?</h2>
    <button id="tombol-faq" type="button" aria-expanded="false" aria-controls="jawaban-faq">
      Lihat jawaban
    </button>
    <p id="jawaban-faq" hidden>
      Pesanan diantar dalam satu sampai dua hari kerja ke alamat seperti Jl. Melati No. 10.
    </p>
  </section>
</body>
</html>

faq-toggle.js

Unduh berkas
javascript
const tombol = document.querySelector("#tombol-faq");
const jawaban = document.querySelector("#jawaban-faq");

tombol.addEventListener("click", function () {
  if (jawaban.hidden) {
    jawaban.hidden = false;
    tombol.setAttribute("aria-expanded", "true");
  } else {
    jawaban.hidden = true;
    tombol.setAttribute("aria-expanded", "false");
  }
});