Topik wawancara representatif

Wawancara Frontend: Kapan CSS scroll-state Queries Dapat Menggantikan Deteksi Scroll JavaScript?

FrontendSulit
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Bagaimana Anda menggunakan kueri scroll-state CSS untuk merespons status sticky, snap, atau scrollable alih-alih mendengarkan event scroll di JavaScript?

Perintah dan kapan ini berlaku

Perintah wawancara: sebuah halaman memiliki heading sticky, kartu snap horizontal, dan petunjuk bahwa masih ada konten yang dapat di-scroll. Bagaimana Anda memutuskan kapan harus mengubah gaya? Bandingkan kueri scroll-state CSS dengan listener scroll JavaScript, dan jelaskan apa yang akan Anda lakukan jika browser tidak memiliki dukungan.

Batasannya adalah styling deklaratif: menambahkan bayangan saat heading menempel (stuck), menyorot kartu yang terpasang (snapped), atau menampilkan petunjuk saat konten masih dapat di-scroll. Status bisnis, gestur kompleks, progres scroll yang presisi, dan pelaporan server tetap menjadi bagian JavaScript. MDN menjelaskan empat kelompok kueri scroll-state: scrollable, scrolled, snapped, dan stuck.

Apa yang dinilai oleh pewawancara

Pewawancara ingin melihat apakah Anda memilih API berdasarkan jenis status lalu menangani batasan dukungan serta aksesibilitas. Jawaban yang kuat menyatakan bahwa container kueri memerlukan container-type dan gaya yang merespons menargetkan elemen turunan (descendant); jawaban ini juga menghindari memperlakukan kueri status CSS sebagai sistem event umum.

Jawaban yang lemah hanya menghafal sintaksis @container. Jawaban yang kuat menjelaskan kapan JavaScript tetap diperlukan, cara menggunakan @supports untuk progressive enhancement, cara menghormati prefers-reduced-motion, dan cara menguji kasus nyata sticky, snap, overflow, serta browser yang tidak didukung.

Pertanyaan klarifikasi sebelum Anda menjawab

Pertama, tanyakan apakah persyaratannya berupa feedback visual atau logika bisnis. Bayangan, warna, dan visibilitas petunjuk cocok untuk CSS; mencatat arah scroll, membuat permintaan jaringan, atau menjalankan state machine membutuhkan JavaScript.

Berikutnya, konfirmasikan sumber status: apakah elemen tersebut benar-benar position: sticky, apakah daftar tersebut menyetel scroll-snap-type, dan apakah container scroll memiliki overflow yang terlihat? Tanpa prasyarat tersebut, kueri terkait akan tetap bernilai false.

Terakhir, konfirmasikan standar dasar browser dan persyaratan animasi. Chrome for Developers mendokumentasikan kueri container scroll-state di Chrome 133; desain produksi harus dimulai dengan gaya yang tidak bergantung pada fitur tersebut, membungkus peningkatan fitur dalam supports, dan menghormati reduced motion.

Kerangka jawaban 30 detik

Katakan sesuatu seperti:

"Saya akan memisahkan status gaya dari event bisnis. Sticky, snap, dan scrollability adalah status browser, jadi saya akan menyetel container-type: scroll-state pada elemen yang relevan dan menggunakan @container dengan scroll-state untuk menata gaya turunannya. Untuk analitik, progres yang tepat, atau aksi bisnis lintas komponen, saya tetap menggunakan JavaScript. Saya akan membuat CSS default dapat digunakan, menambahkan fitur tersebut di balik @supports, menonaktifkan animasi yang tidak esensial bagi pengguna reduced-motion, serta menguji overflow, snap, input keyboard, dan browser yang tidak didukung."

Jawaban mendalam langkah demi langkah

Menetapkan container kueri scroll-state

Deklarasikan elemen yang statusnya akan dikueri sebagai container scroll-state. Beri nama jika beberapa container berpotensi cocok:

css
.sticky-heading {
  position: sticky;
  top: 0;
  container-type: scroll-state;
  container-name: heading;
}

Aturan yang merespons harus menargetkan elemen turunan, bukan elemen yang sama yang memiliki container-type. Panduan Chrome menunjukkan hubungan lapisan proxy ini secara eksplisit.

Memilih deskriptor berdasarkan status

stuck memeriksa apakah elemen sticky menempel pada tepi; snapped memeriksa apakah elemen akan terpasang (snap) ke container snap; scrollable memeriksa apakah masih ada overflow dalam suatu arah; scrolled memeriksa arah scroll terbaru. Kueri-kueri ini menjawab pertanyaan berbeda dan tidak dapat dipertukarkan.

Sebagai contoh, tambahkan bayangan pada navigasi saat menempel (stuck):

css
@container heading scroll-state(stuck: top) {
  .nav {
    box-shadow: 0 5px 12px rgb(0 0 0 / 18%);
  }
}

Menempatkan target gaya di bawah container

Mengubah latar belakang langsung pada elemen yang memiliki container-type membuat aturan pemisahan mudah dilanggar. Pertahankan wrapper internal sebagai target respons. Komponen tetap dapat digunakan kembali dan transisi status lebih mudah diuji.

Menggunakan scrollable untuk keterlihatan konten (discoverability)

Untuk daftar kartu horizontal, tampilkan petunjuk gradien saat daftar masih dapat di-scroll ke arah akhir inline-nya:

css
.carousel {
  container-type: scroll-state;
  container-name: cards;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}

@container cards scroll-state(scrollable: inline-end) {
  .next-hint {
    opacity: 1;
  }
}

Petunjuk tersebut bersifat pelengkap. Jangan mengomunikasikan "konten tambahan" hanya melalui warna; pertahankan scrolling keyboard, fokus yang terlihat, dan label teks.

Menggunakan snapped untuk feedback kartu saat ini

snapped hanya bermakna jika terdapat ancestor snap dan sumbu snap yang valid. Menyorot kartu saat ini dapat meningkatkan feedback visual, tetapi ini bukan sinyal komit pemilihan bisnis yang dapat diandalkan. Pemilihan yang sebenarnya tetap membutuhkan kontrol yang aksesibel dan status JavaScript.

Menggunakan scrolled untuk feedback arah

Bilah alat (toolbar) atas dapat bereaksi terhadap arah scroll terbaru, tetapi pergerakan terarah dapat menambah beban kognitif. Buat agar tetap aksesibel secara default; gunakan scrolled: block-start atau block-end hanya jika manfaatnya jelas, dan tambahkan transisi.

Progressive enhancement dan fallback

Gaya dasar harus tetap dapat digunakan saat scroll-state tidak didukung:

css
.nav {
  box-shadow: none;
}

@supports (container-type: scroll-state) {
  .sticky-heading {
    container-type: scroll-state;
  }

  @container scroll-state(stuck: top) {
    .nav {
      box-shadow: 0 5px 12px rgb(0 0 0 / 18%);
    }
  }
}

Jika browser lama harus menerima petunjuk serupa, gunakan fallback terbatas dengan IntersectionObserver atau ResizeObserver. Jangan membuat ulang seluruh loop scroll-event pada fallback.

Animasi dan verifikasi

Chrome menyarankan untuk menempatkan animasi yang tidak esensial di balik prefers-reduced-motion: no-preference. Uji tepi atas dan bawah, tanpa overflow, pengoperasian keyboard, scrolling sentuh, status perantara snap, zoom, dan browser yang tidak didukung. Pastikan bahwa perubahan status tidak pernah menyembunyikan fokus atau konten.

Contoh jawaban berkualitas tinggi

"Pertama, saya akan bertanya apakah ini feedback visual atau event bisnis. Untuk bayangan sticky, sorotan snap, atau petunjuk scroll, saya akan menyetel container-type: scroll-state pada elemen sticky atau snapping dan menggunakan kueri stuck, snapped, atau scrollable agar elemen turunan merespons. Analitik, perhitungan progres, dan pengiriman seleksi tetap berada di JavaScript. Saya akan merilis CSS default yang dapat digunakan, menambahkan peningkatan di balik @supports, mempertahankan fallback statis, dan mengurangi animasi jika diminta. Saya akan menguji overflow nyata, snap, input keyboard, dan browser lama."

Kesalahan umum

Memperlakukan scroll-state sebagai event scroll

Pola kegagalan: menggunakan kueri untuk memicu analitik, permintaan data, atau pengiriman bisnis. Mengapa gagal: CSS mengekspresikan kondisi gaya, bukan payload event atau waktu bisnis yang dapat diandalkan. Solusi: pertahankan styling di CSS dan aksi bisnis di kontrol semantik plus JavaScript.

Melupakan container kueri

Pola kegagalan: menulis @container scroll-state(stuck: top) tanpa container-type: scroll-state. Mengapa gagal: browser tidak memiliki sumber status untuk dievaluasi. Solusi: verifikasi prasyarat sticky, snap, atau overflow, lalu deklarasikan container bernama.

Menata gaya container itu sendiri

Pola kegagalan: menjadikan satu elemen sebagai container sekaligus target gaya status. Mengapa gagal: kueri menargetkan elemen turunan, dan strukturnya menjadi rapuh. Solusi: tambahkan wrapper internal dan terapkan feedback status di sana.

Mengganti feedback yang aksesibel hanya dengan warna

Pola kegagalan: hanya mengubah warna untuk menampilkan kartu snap saat ini atau konten tambahan. Mengapa gagal: warna saja tidak menyampaikan status secara andal dan dapat mengecualikan pengguna dengan gangguan penglihatan (low-vision). Solusi: sediakan teks, fokus, kontrol, atau petunjuk scroll yang dapat ditindaklanjuti.

Mengabaikan batasan dukungan dan animasi

Pola kegagalan: mengasumsikan setiap browser mendukung fitur ini dan memaksakan gerakan selama scroll. Mengapa gagal: browser lama mengalami degradasi dan gerakan dapat menyebabkan ketidaknyamanan. Solusi: gunakan @supports, pertahankan default yang dapat digunakan, dan hormati reduced-motion.

Pertanyaan lanjutan dan tanggapan

Bagaimana jika Anda membutuhkan persentase scroll yang tepat?

scroll-state mengekspos status diskret, bukan persentase kontinu. Gunakan JavaScript untuk membaca rentang scroll dan melakukan throttle pada pembaruan, memisahkan pembacaan, komputasi, dan penulisan sehingga setiap event scroll tidak memicu tata letak (layout) secara sinkron.

Bagaimana jika kueri sticky selalu bernilai false?

Periksa containing block dari elemen sticky, top atau inset, overflow ancestor, dan apakah elemen tersebut benar-benar memasuki rentang sticky-nya. Hanya setelah itu periksa container-type dan selektor turunan.

Bagaimana jika sorotan snap berkedip (flicker)?

Periksa sumbu snap, scroll-snap-align, dan dimensi target. Hindari transisi pada properti yang sering mengubah tata letak. Jaga agar status fokus dan seleksi tetap eksplisit; penyorotan hanyalah status visual.

Bagaimana jika browser lama harus terlihat sama persis?

Tentukan gaya statis yang dapat digunakan terlebih dahulu, lalu tambahkan fallback kecil dengan IntersectionObserver atau ResizeObserver untuk petunjuk utama. Jangan menyalin sistem listener scroll yang rumit; jika biaya peningkatan lebih besar daripada manfaatnya, terima bayangan statis atau petunjuk yang selalu terlihat.

Bagaimana jika pengguna lebih memilih gerakan yang dikurangi (reduced motion)?

Pertahankan hierarki informasi tanpa translasi atau penskalaan paksa. Ubah hanya bayangan, batas tepi, atau warna statis, dan biarkan prefers-reduced-motion menimpa transisi dan animasi.

Sumber publik

Pertanyaan terkait