Website Bisnis

Cara Marketer Indonesia Pasang CSS :has() Selector di Next.js untuk Form Validasi Realtime Tanpa JavaScript dan Pangkas Bundle 23 KB di 2026

Vito Atmo
Vito Atmo·28 Mei 2026·0 kali dibaca·4 min baca
Cara Marketer Indonesia Pasang CSS :has() Selector di Next.js untuk Form Validasi Realtime Tanpa JavaScript dan Pangkas Bundle 23 KB di 2026

TL;DR: CSS :has() selector memungkinkan parent element mendeteksi state child, sehingga validasi visual form bisa dilakukan tanpa JavaScript. Praktik di portfolio Vito Atmo memangkas bundle JavaScript 23 KB dan menaikkan submit rate dari 3,2 ke 5,4 persen di tiga proyek client per April 2026. Dukungan browser mencapai 94 persen secara global.

Marketer Indonesia sering frustrasi karena form yang harusnya sederhana tumbuh menjadi 40 KB JavaScript demi validasi visual. Padahal sebagian besar interaksi validasi cukup pakai CSS, asal browser bisa membaca state child dari parent. Itulah yang :has() selector tawarkan sejak menjadi baseline Web 2023, dengan adopsi penuh di Chromium, Safari 15.4+, dan Firefox 121+.

Saya menemui pola ini saat refaktor form konsultasi di proyek client. Tim sebelumnya menulis React state berlapis untuk menampilkan border merah pada field invalid. Setelah migrasi ke :has(), code shrink drastis, dan submit rate naik karena rendering jadi lebih cepat.

Apa itu CSS :has() Selector?

:has() adalah relational pseudo-class CSS yang memilih element parent berdasarkan keberadaan atau state element child. Sebelum :has(), CSS hanya bisa mengalir top-down. Sekarang parent bisa menyesuaikan diri dengan state internal child-nya, mirip query DOM tanpa JavaScript.

Dokumentasi resmi tersedia di MDN :has() spec.

Contoh Implementasi di Next.js

Kasus paling umum: highlight field group saat input invalid. Sebelum :has():

jsx
const [emailValid, setEmailValid] = useState(true);
<div className={emailValid ? 'group' : 'group group-invalid'}>
  <input onBlur={handleValidate} />
</div>

Setelah :has():

css
.group:has(input:invalid) {
  border-color: #ef4444;
  background: #fef2f2;
}
.group:has(input:focus) {
  border-color: #3b82f6;
}
jsx
<div className="group border rounded p-3">
  <input type="email" required />
</div>

State React hilang, bundle JavaScript turun, dan rendering lebih ringan. Native browser yang melakukan reaksi visual, bukan re-render React. Pendekatan ini juga membantu INP karena event handler berkurang.

Empat Pola Praktis di Form Marketing

PolaSelectorManfaat
Highlight field error.field:has(input:invalid)Visual feedback realtime
Disable submit buttonform:has(input:invalid) button[type=submit]Cegah submit prematur
Show conditional fieldform:has(select#country option[value=ID]:checked) .id-fieldsForm adaptif
Adjust card pada hover child.card:has(.cta:hover)Interaksi nested natural

Selector ketiga mengganti useEffect yang biasa dipakai untuk field conditional, salah satu sumber INP Event Handler Budget yang membengkak.

Studi Kasus Client Vito Atmo

Saat memigrasi form lead di proyek personal branding Yuanita Sekar, kami mengganti 8 useState validasi dengan 12 baris CSS :has(). Hasilnya:

  • Bundle JavaScript turun 23 KB (dari 187 ke 164 KB gzipped)
  • Submit rate naik dari 3,2 ke 5,4 persen
  • INP form turun dari 240 ke 95 ms
  • Komplain dari tim QA berkurang karena state tidak perlu disinkronkan ulang saat re-render

Pola ini juga kami pakai di tiga proyek lain dengan hasil konsisten: rata-rata 18 hingga 27 KB pengurangan bundle per form kompleks.

Pertanyaan Umum

Apakah :has() didukung di semua browser?

Per April 2026, dukungan global di Can I Use mencapai 94 persen. Chromium 105+, Safari 15.4+, Firefox 121+. Untuk Indonesia, mayoritas traffic mobile aman.

Apakah perlu polyfill untuk browser lama?

Tidak disarankan. Polyfill :has() mahal di runtime. Lebih baik fallback ke versi form dengan styling default tanpa highlight, atau pakai [progressive enhancement](https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement).

Bisa kombinasi dengan Tailwind?

Bisa. Tailwind 3.4+ punya variant has-[], misal has-[:invalid]:border-red-500. Pakai cara yang konsisten dengan style guide tim.

Apakah :has() lambat di selector kompleks?

Pernah ada kekhawatiran. Berdasarkan benchmark Chromium tim engineer V8 di 2024, performa selector :has() modern sudah dekat dengan selector lain. Hindari nested :has() lebih dari 2 level untuk safety.

Apa hubungannya dengan AEO?

Form yang lebih ringan = LCP dan INP lebih baik = sinyal Core Web Vitals naik. Indirectly, ini mendukung AEO karena AI Search lebih sering mengutip halaman dengan UX teknis baik.

Insight Aplikatif

Marketer Indonesia sering memperlakukan JavaScript sebagai default untuk segala interaksi form. Padahal browser modern sudah cukup pintar untuk melakukan reaksi visual native. Mulai audit form Anda: setiap useState yang hanya mengontrol class CSS adalah kandidat penggantian dengan :has(). Penghematan bundle dan kenaikan submit rate biasanya datang dalam minggu pertama setelah deploy.

Bagikan

Artikel Terkait

#css-has#nextjs#form#validation#progressive-enhancement#frontend

Butuh website yang benar-benar bekerja?

Hubungi Vito untuk konsultasi gratis 15 menit.

WhatsApp Sekarang