CSS WEB-API FRONTEND UI-UX WEB-STANDARDS JAVASCRIPT PERFORMANCE-OPTIMIZATION ACCESSIBILITY DEVELOPER-EXPERIENCE MODERN-WEB

CSS Custom Highlight API: Membangun Fitur Penanda Teks Kustom yang Powerful dan Efisien di Web

⏱️ 20 menit baca
👨‍💻

CSS Custom Highlight API: Membangun Fitur Penanda Teks Kustom yang Powerful dan Efisien di Web

1. Pendahuluan

Pernahkah Anda mencoba membangun fitur pencarian di aplikasi web yang menyorot semua kemunculan kata kunci? Atau mungkin Anda ingin membuat editor teks dengan penyorotan sintaks (syntax highlighting) yang dinamis? Secara tradisional, tugas-tugas ini seringkali terasa seperti menggali lubang yang semakin dalam. Kita biasanya berakhir dengan memanipulasi DOM secara manual, menyisipkan elemen <span> di sana-sini untuk menandai teks.

Pendekatan ini, meskipun fungsional, seringkali membawa serangkaian masalah: ❌ Performa Buruk: Manipulasi DOM, terutama untuk konten yang besar atau sering berubah, bisa sangat mahal dan menyebabkan jank pada UI. ❌ Kompleksitas Kode: Logika untuk menyisipkan, memperbarui, dan menghapus elemen penanda bisa menjadi sangat rumit dan rentan bug. ❌ Masalah Aksesibilitas: Menyisipkan elemen tambahan ke dalam DOM dapat mengganggu struktur semantik dan pengalaman pengguna assistive technologies. ❌ Penanganan Edge Cases: Tumpang tindih highlight, teks yang dinamis, atau highlight yang mencakup batas elemen HTML bisa menjadi mimpi buruk.

Kabar baiknya, ada solusi yang lebih elegan, efisien, dan sesuai standar web: CSS Custom Highlight API. API ini memungkinkan kita untuk mendefinisikan “highlight” kustom secara deklaratif dan men-style-nya menggunakan CSS, tanpa perlu menyentuh struktur DOM yang mendasarinya. Ini seperti memiliki lapisan “virtual” di atas teks Anda yang bisa di-style sesuka hati.

Dalam artikel ini, kita akan menyelami CSS Custom Highlight API. Kita akan memahami cara kerjanya, mengapa ini menjadi game-changer, dan bagaimana Anda bisa mengimplementasikannya untuk membangun fitur penanda teks yang powerful dan performa tinggi di aplikasi web Anda. Mari kita mulai!

2. Apa Itu CSS Custom Highlight API?

📌 CSS Custom Highlight API adalah standar web baru yang memungkinkan developer membuat “highlight” teks kustom yang dapat di-style menggunakan CSS. Poin kuncinya adalah highlight ini tidak memodifikasi DOM yang mendasarinya. Sebaliknya, highlight ini bertindak seperti lapisan virtual yang digambar oleh browser di atas teks Anda.

Bayangkan Anda memiliki sebuah paragraf teks. Jika Anda ingin menyorot beberapa kata di dalamnya, secara tradisional Anda akan membungkus kata-kata tersebut dengan <span style="background-color: yellow;">...</span>. Dengan Custom Highlight API, Anda hanya perlu memberi tahu browser “kata-kata ini harus dihighlight dengan nama ‘cari-saya’”, lalu di CSS Anda mendefinisikan ::highlight(cari-saya) untuk memberikan gaya (misalnya, background-color: yellow;).

API ini terdiri dari dua bagian utama:

  1. JavaScript API (CSS.highlights): Digunakan untuk mendaftarkan highlight baru dan menentukan bagian teks mana yang harus di-highlight. Anda bekerja dengan objek Range JavaScript untuk mendefinisikan segmen teks.
  2. CSS Pseudo-element (::highlight()): Digunakan untuk memberikan gaya pada highlight yang telah Anda daftarkan melalui JavaScript.

Ini adalah pergeseran paradigma yang signifikan. Alih-alih memanipulasi DOM, kita memberikan instruksi kepada browser tentang bagaimana cara menggambar highlight, dan browser akan menangani renderingnya secara efisien.

3. Mengapa Kita Membutuhkannya? Masalah yang Dipecahkan

Custom Highlight API hadir untuk mengatasi banyak kekurangan dari pendekatan penyorotan teks tradisional berbasis manipulasi DOM. Mari kita lihat lebih detail:

❌ Masalah dengan Pendekatan Tradisional (Manipulasi DOM)

✅ Keunggulan CSS Custom Highlight API

Dengan Custom Highlight API, kita mendapatkan efisiensi dan kekuatan browser, sambil menjaga kode tetap bersih dan pengalaman pengguna tetap optimal.

4. Cara Kerja CSS Custom Highlight API: JavaScript dan CSS Bersatu

Memanfaatkan CSS Custom Highlight API melibatkan dua langkah utama: mendefinisikan rentang teks yang akan di-highlight menggunakan JavaScript, dan kemudian men-style highlight tersebut menggunakan CSS.

Langkah 1: Mendefinisikan Highlight dengan JavaScript

Kita menggunakan objek global CSS.highlights untuk mengelola highlight. Metode utamanya adalah CSS.highlights.set(name, ranges).

Untuk membuat objek Range, Anda bisa menggunakan document.createRange(). Objek Range memiliki properti seperti setStart() dan setEnd() yang memungkinkan Anda menentukan titik awal dan akhir dari highlight. Titik-titik ini biasanya berupa Node dan offset di dalam Node tersebut.

💡 Contoh JavaScript:

Misalkan kita punya paragraf berikut:

<p id="myParagraph">Ini adalah contoh teks yang akan kita highlight. Kita akan mencari kata "highlight" dan "teks".</p>

Dan kita ingin menyorot semua kemunculan kata “highlight” dan “teks”.

// Pastikan browser mendukung Custom Highlight API
if (CSS.highlights) {
    const paragraph = document.getElementById('myParagraph');
    const textContent = paragraph.textContent; // Ambil seluruh teks dalam paragraf

    const highlightRanges = new Set();
    const searchTerm1 = "highlight";
    const searchTerm2 = "teks";

    // Fungsi pembantu untuk mencari dan membuat Range
    function findAndCreateRanges(textNode, searchTerm) {
        const text = textNode.textContent;
        let startIndex = 0;
        while ((startIndex = text.indexOf(searchTerm, startIndex)) !== -1) {
            const range = document.createRange();
            range.setStart(textNode, startIndex);
            range.setEnd(textNode, startIndex + searchTerm.length);
            highlightRanges.add(range);
            startIndex += searchTerm.length;
        }
    }

    // Karena textContent mungkin tersebar di beberapa textNode (jika ada elemen lain di dalamnya)
    // Untuk contoh sederhana ini, kita asumsikan satu textNode langsung di dalam <p>
    // Dalam kasus nyata, Anda perlu iterasi melalui childNodes untuk menemukan textNode yang relevan.
    const textNode = paragraph.firstChild; // Asumsi: Teks langsung di dalam P

    if (textNode && textNode.nodeType === Node.TEXT_NODE) {
        findAndCreateRanges(textNode, searchTerm1);
        findAndCreateRanges(textNode, searchTerm2);
    }

    // Daftarkan highlight dengan nama 'cari-saya'
    CSS.highlights.set('cari-saya', highlightRanges);
    console.log('Highlight telah didaftarkan!');

    // Untuk menghapus highlight:
    // CSS.highlights.clear(); // Menghapus semua highlight
    // CSS.highlights.delete('cari-saya'); // Menghapus highlight dengan nama 'cari-saya'

} else {
    console.warn('Browser Anda tidak mendukung CSS Custom Highlight API.');
}

Dalam contoh di atas, kita:

  1. Mendapatkan elemen paragraf.
  2. Mendapatkan TextNode pertama dari paragraf (ini penting, karena Range bekerja pada TextNode bukan elemen HTML).
  3. Mencari kata kunci dan membuat objek Range untuk setiap kemunculan.
  4. Menambahkan semua Range ini ke dalam sebuah Set.
  5. Memanggil CSS.highlights.set('cari-saya', highlightRanges) untuk memberi tahu browser bahwa semua Range dalam highlightRanges harus di-highlight dengan nama cari-saya.

Langkah 2: Styling Highlight dengan CSS

Setelah Anda mendaftarkan highlight dengan JavaScript, Anda bisa men-style-nya menggunakan pseudo-element ::highlight().

/* Styling untuk highlight dengan nama 'cari-saya' */
::highlight(cari-saya) {
    background-color: yellow;
    color: black;
    /* Properti lain yang didukung:
       - text-decoration (underline, overline, line-through)
       - text-emphasis
       - text-shadow
       - font-weight
       - font-style
       - dll.
       Properti seperti padding, margin, border, tidak didukung karena ini bukan elemen DOM nyata.
    */
    text-decoration: underline wavy red;
}

/* Anda juga bisa men-style highlight default seperti ::selection */
::selection {
    background-color: #007bff;
    color: white;
}

Dengan CSS di atas, setiap bagian teks yang didaftarkan sebagai cari-saya oleh JavaScript akan secara otomatis memiliki latar belakang kuning, teks hitam, dan garis bawah bergelombang merah. Semudah itu!

5. Contoh Praktis: Fitur Pencarian Teks Dinamis

Mari kita gabungkan JavaScript dan CSS untuk membuat fitur pencarian teks dinamis yang menyorot hasil pencarian di halaman. Ini adalah salah satu kasus penggunaan paling umum dan demonstratif untuk API ini.

🎯 Tujuan: Membuat input pencarian yang saat diketik, akan menyorot semua kemunculan teks yang dicari di dalam sebuah area konten, tanpa mengganggu DOM.

<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Demo CSS Custom Highlight API</title>
    <style>
        body {
            font-family: sans-serif;
            margin: 20px;
            line-height: 1.6;
        }
        .container {
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            border: 1px solid #eee;
            box-shadow: 0 0 10px rgba(0,0,0,0.05);
        }
        input[type="text"] {
            width: 100%;
            padding: 10px;
            margin-bottom: 20px;
            border: 1px solid #ccc;
            border-radius: 4px;
            font-size: 1em;
        }

        /* ✅ Styling highlight dengan CSS Custom Highlight API */
        ::highlight(search-result) {
            background-color: #ffd700; /* Warna kuning keemasan */
            color: #333;
            text-decoration: underline;
            /* Anda bisa menambahkan text-shadow atau font-weight juga */
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Mencari Teks dengan CSS Custom Highlight API</h1>
        <input type="text" id="searchInput" placeholder="Ketik kata kunci untuk mencari...">

        <div id="contentArea">
            <p>Selamat datang di blog saya. Artikel ini membahas tentang **CSS Custom Highlight API**, sebuah standar web baru yang sangat berguna untuk developer frontend. Dengan API ini, kita bisa menyorot teks tanpa memanipulasi DOM, yang berarti performa aplikasi web akan tetap optimal. Contoh penggunaan yang paling umum adalah fitur pencarian, di mana pengguna dapat dengan mudah menemukan kata kunci yang mereka cari di dalam sebuah dokumen.</p>
            <p>Selain pencarian, API ini juga memiliki potensi besar untuk implementasi fitur-fitur canggih seperti syntax highlighting pada editor kode, penandaan revisi dalam dokumen kolaboratif, atau bahkan alat bantu membaca untuk aksesibilitas. Kemampuan untuk men-style highlight secara deklaratif melalui CSS membuat proses pengembangan menjadi jauh lebih bersih dan efisien. Mari kita **eksplorasi** lebih lanjut!</p>
            <p>Pastikan browser Anda mendukung `CSS.highlights` untuk melihat demo ini bekerja dengan baik. Jika tidak, Anda mungkin tidak akan melihat highlight apa pun, namun logika JavaScript akan tetap berjalan. Ini adalah contoh bagaimana web development terus **berinovasi**.</p>
        </div>
    </div>

    <script>
        if (CSS.highlights) {
            const searchInput = document.getElementById('searchInput');
            const contentArea = document.getElementById('contentArea');

            // Fungsi untuk mencari teks dan menerapkan highlight
            function applyHighlights(searchTerm) {
                // Hapus highlight sebelumnya
                CSS.highlights.delete('search-result');

                if (!searchTerm) {
                    return; // Jika kosong, tidak ada yang perlu dihighlight
                }

                const ranges = new Set();
                const walker = document.createTreeWalker(
                    contentArea,
                    NodeFilter.SHOW_TEXT,
                    null,
                    false
                );

                let node;
                while ((node = walker.nextNode())) {
                    const text = node.textContent;
                    let startIndex = 0;
                    while ((startIndex = text.toLowerCase().indexOf(searchTerm.toLowerCase(), startIndex)) !== -1) {
                        const range = document.createRange();
                        range.setStart(node, startIndex);
                        range.setEnd(node, startIndex + searchTerm.length);
                        ranges.add(range);
                        startIndex += searchTerm.length;
                    }
                }

                // Terapkan highlight baru
                CSS.highlights.set('search-result', ranges);
            }

            // Gunakan event listener untuk input pencarian
            searchInput.addEventListener('input', (event) => {
                applyHighlights(event.target.value);
            });

            // Panggil sekali saat dimuat untuk highlight awal jika ada teks
            applyHighlights(searchInput.value);

        } else {
            document.body.innerHTML = `
                <div class="container">
                    <h1>Browser Tidak Mendukung CSS Custom Highlight API</h1>
                    <p>Maaf, browser Anda tidak mendukung <code>CSS.highlights</code>. Anda tidak akan melihat fitur penyorotan teks pada demo ini.</p>
                    <p>Coba gunakan browser modern seperti Chrome (versi 105+), Edge, atau Firefox (dengan flag).</p>
                </div>
            `;
            console.warn('Browser Anda tidak mendukung CSS Custom Highlight API.');
        }
    </script>
</body>
</html>

Dalam contoh ini:

  1. HTML: Kita memiliki sebuah input untuk pencarian dan div dengan id="contentArea" yang berisi teks yang akan dicari.
  2. CSS: Kita mendefinisikan gaya untuk ::highlight(search-result). Ini adalah nama yang akan kita gunakan di JavaScript.
  3. JavaScript:
    • Kita memeriksa dukungan browser untuk CSS.highlights.
    • Fungsi applyHighlights(searchTerm) adalah intinya:
      • Pertama, ia menghapus highlight sebelumnya dengan CSS.highlights.delete('search-result') untuk memastikan hanya highlight terbaru yang ditampilkan.
      • Kemudian, ia menggunakan document.createTreeWalker untuk menelusuri semua TextNode di dalam contentArea. Ini adalah cara yang lebih robust untuk mencari teks di DOM yang mungkin memiliki struktur nested.
      • Untuk setiap TextNode, ia mencari searchTerm (case-insensitive) dan membuat objek Range untuk setiap kemunculan.
      • Semua Range ini dikumpulkan dalam sebuah Set.
      • Akhirnya, CSS.highlights.set('search-result', ranges) dipanggil untuk menerapkan highlight baru.
    • Event listener input pada searchInput memanggil applyHighlights setiap kali pengguna mengetik, menciptakan pengalaman pencarian real-time yang sangat responsif.

Coba jalankan kode ini di browser yang mendukung (misalnya, Chrome terbaru). Anda akan melihat bagaimana teks hasil pencarian disorot secara instan tanpa ada kedipan atau lag, bahkan saat Anda mengetik cepat.

6. Beyond Search: Use Case Menarik Lainnya

CSS Custom Highlight API jauh melampaui sekadar fitur pencarian. Potensinya sangat besar untuk berbagai aplikasi web modern:

Potensi untuk inovasi UI/UX dengan API ini sangat besar, membuka pintu bagi pengalaman web yang sebelumnya sulit atau tidak efisien untuk diimplementasikan.

7. Tips dan Best Practices

Untuk memaksimalkan penggunaan CSS Custom Highlight API, perhatikan beberapa tips dan praktik terbaik ini: