Ikhtisar Praktis CSS Houdini

Diterbitkan: 2022-03-10
Ringkasan cepat Houdini, istilah umum untuk kumpulan API browser, bertujuan untuk membawa peningkatan signifikan pada proses pengembangan web dan pengembangan standar CSS secara umum. Pengembang frontend akan dapat memperluas CSS dengan fitur baru menggunakan JavaScript, menghubungkan ke mesin rendering CSS, dan memberi tahu browser cara menerapkan CSS selama proses render. Dukungan browser Houdini meningkat dan beberapa API tersedia untuk digunakan saat ini, jadi inilah saat yang tepat untuk mengenalnya dan bereksperimen. Kami akan melihat setiap bagian dari Houdini, dukungan browser saat ini dan melihat bagaimana mereka dapat digunakan hari ini menggunakan peningkatan progresif.

Perlu waktu lama bagi fitur atau peningkatan CSS baru untuk berkembang dari draf awal ke fitur CSS yang didukung penuh dan stabil yang dapat digunakan pengembang. Polyfill berbasis JavaScript dapat digunakan sebagai pengganti kurangnya dukungan browser untuk menggunakan fitur CSS baru sebelum diimplementasikan secara resmi. Tetapi mereka cacat dalam banyak kasus. Misalnya, scrollsnap-polyfill adalah salah satu dari beberapa polyfill yang dapat digunakan untuk memperbaiki inkonsistensi dukungan browser untuk spesifikasi CSS Scroll Snap. Tetapi bahkan solusi itu memiliki beberapa keterbatasan, bug, dan inkonsistensi.

Kelemahan potensial menggunakan polyfill adalah mereka dapat berdampak negatif pada kinerja dan sulit untuk diterapkan dengan benar. Kelemahan ini terkait dengan DOM dan CSSOM browser. Browser membuat DOM (Document Object Model) dari markup HTML dan, sama halnya, membuat CSSOM (CSS Object Model) dari markup CSS. Kedua pohon objek ini independen satu sama lain. JavaScript berfungsi di DOM dan memiliki akses yang sangat terbatas ke CSSOM.

Solusi JavaScript Polyfill hanya berjalan setelah siklus render awal selesai, yaitu ketika DOM dan CSSOM telah dibuat dan dokumen telah selesai dimuat. Setelah Polyfill membuat perubahan pada gaya di DOM (dengan menyejajarkannya), hal itu menyebabkan proses render berjalan kembali dan seluruh halaman dirender ulang. Dampak kinerja negatif menjadi lebih jelas jika mengandalkan metode requestAnimationFrame atau bergantung pada interaksi pengguna seperti peristiwa gulir.

Kendala lain dalam pengembangan web adalah berbagai kendala yang dikenakan oleh standar CSS . Misalnya, hanya ada sejumlah properti CSS yang dapat dianimasikan secara native. CSS tahu cara menganimasikan warna secara native, tetapi tidak tahu cara menganimasikan gradien. Selalu ada kebutuhan untuk berinovasi dan menciptakan pengalaman web yang mengesankan dengan mendorong batas meskipun ada keterbatasan teknologi. Itulah sebabnya pengembang sering cenderung menggunakan solusi yang kurang ideal atau JavaScript untuk menerapkan gaya dan efek yang lebih canggih yang saat ini tidak didukung oleh CSS seperti tata letak batu, efek 3D lanjutan, animasi lanjutan, tipografi lancar, gradien animasi, elemen select yang ditata, dll.

Tampaknya tidak mungkin bagi spesifikasi CSS untuk mengikuti berbagai tuntutan fitur dari industri seperti kontrol yang lebih besar atas animasi, pemotongan teks yang ditingkatkan, opsi gaya yang lebih baik untuk elemen input dan select , opsi display yang lebih banyak, opsi filter yang lebih banyak, dll.

Apa yang bisa menjadi solusi potensial? Berikan pengembang cara asli untuk memperluas CSS menggunakan berbagai API . Pada artikel ini, kita akan melihat bagaimana developer frontend dapat melakukannya menggunakan Houdini API, JavaScript, dan CSS. Di setiap bagian, kita akan memeriksa setiap API satu per satu, memeriksa dukungan browser dan status spesifikasi saat ini, dan melihat bagaimana penerapannya saat ini menggunakan peningkatan Progresif.

Lebih banyak setelah melompat! Lanjutkan membaca di bawah ini

Apa Itu Houdini?

Houdini, istilah umum untuk kumpulan API browser, bertujuan untuk membawa peningkatan signifikan pada proses pengembangan web dan pengembangan standar CSS secara umum. Pengembang akan dapat memperluas CSS dengan fitur baru menggunakan JavaScript, menghubungkan ke mesin rendering CSS, dan memberi tahu browser cara menerapkan CSS selama proses render. Ini akan menghasilkan kinerja dan stabilitas yang jauh lebih baik daripada menggunakan polyfill biasa.

Spesifikasi Houdini terdiri dari dua grup API - API tingkat tinggi dan API tingkat rendah .

API tingkat tinggi terkait erat dengan proses rendering browser (gaya → tata letak → cat → komposit). Ini termasuk:

  • API Cat
    Titik ekstensi untuk langkah rendering cat browser di mana properti visual (warna, latar belakang, batas, dll.) ditentukan.
  • API Tata Letak
    Titik ekstensi untuk langkah rendering tata letak browser tempat dimensi elemen, posisi, dan perataan ditentukan.
  • API Animasi
    Titik ekstensi untuk langkah rendering komposit browser di mana lapisan digambar ke layar dan dianimasikan.

API Tingkat Rendah membentuk dasar untuk API tingkat tinggi. Ini termasuk:

  • API Model Objek yang Diketik
  • Properti Kustom & Nilai API
  • API Metrik Font
  • Worklet

Beberapa API Houdini sudah tersedia untuk digunakan di beberapa browser dengan API lain untuk mengikutinya saat siap dirilis.

Masa Depan CSS

Tidak seperti spesifikasi fitur CSS biasa yang telah diperkenalkan sejauh ini, Houdini menonjol dengan memungkinkan pengembang untuk memperluas CSS dengan cara yang lebih asli. Apakah ini berarti spesifikasi CSS akan berhenti berkembang dan tidak ada implementasi resmi baru dari fitur CSS yang akan dirilis? Nah, itu tidak terjadi. Tujuan Houdini adalah untuk membantu proses pengembangan fitur CSS dengan memungkinkan pengembang untuk membuat prototipe kerja yang dapat dengan mudah distandarisasi.

Selain itu, pengembang akan dapat membagikan Worklet CSS open-source dengan lebih mudah dan dengan lebih sedikit kebutuhan untuk perbaikan bug khusus browser.

API Model Objek yang Diketik

Sebelum Houdini diperkenalkan, satu-satunya cara JavaScript untuk berinteraksi dengan CSS adalah dengan menguraikan CSS yang direpresentasikan sebagai nilai string dan memodifikasinya. Mengurai dan mengganti gaya secara manual bisa jadi sulit dan rawan kesalahan karena jenis nilai perlu diubah bolak-balik dan unit nilai perlu ditambahkan secara manual saat menetapkan nilai baru.

 selectedElement.style.fontSize = newFontSize + "px"; // newFontSize = 20 console.log(selectedElement.style.fontSize); // "20px"

Typed Object Model (Typed OM) API menambahkan lebih banyak makna semantik ke nilai CSS dengan mengeksposnya sebagai objek JavaScript yang diketik. Ini secara signifikan meningkatkan kode terkait dan membuatnya lebih berkinerja, stabil, dan dapat dipelihara. Nilai CSS diwakili oleh antarmuka CSSUnitValue yang terdiri dari nilai dan properti unit.

 { value: 20, unit: "px" }

Antarmuka baru ini dapat digunakan dengan properti baru berikut:

  • computedStyleMap() : untuk menguraikan gaya yang dihitung (non-inline). Ini adalah metode elemen terpilih yang perlu dipanggil sebelum menguraikan atau menggunakan metode lain.
  • attributeStyleMap : untuk menguraikan dan memodifikasi gaya sebaris. Ini adalah properti yang tersedia pada elemen yang dipilih.
 // Get computed styles from stylesheet (initial value) selectedElement.computedStyleMap().get("font-size"); // { value: 20, unit: "px"} // Set inline styles selectedElement.attributeStyleMap.set("font-size", CSS.em(2)); // Sets inline style selectedElement.attributeStyleMap.set("color", "blue"); // Sets inline style // Computed style remains the same (initial value) selectedElement.computedStyleMap().get("font-size"); // { value: 20, unit: "px"} // Get new inline style selectedElement.attributeStyleMap.get("font-size"); // { value: 2, unit: "em"}

Perhatikan bagaimana jenis CSS tertentu digunakan saat menyetel nilai numerik baru. Dengan menggunakan sintaks ini, banyak potensi masalah terkait tipe dapat dihindari dan kode yang dihasilkan lebih andal dan bebas bug.

Metode get dan set hanyalah sebagian kecil dari semua metode yang tersedia yang ditentukan oleh Typed OM API. Beberapa di antaranya adalah:

  • clear : menghapus semua gaya sebaris
  • delete : menghapus properti CSS yang ditentukan dan nilainya dari gaya sebaris
  • has : mengembalikan boolean jika properti CSS yang ditentukan disetel
  • append : menambahkan nilai tambahan ke properti yang mendukung banyak nilai
  • dll.

Deteksi fitur

 var selectedElement = document.getElementById("example"); if(selectedElement.attributeStyleMap) { /* ... */ } if(selectedElement.computedStyleMap) { /* ... */ }

Status Spesifikasi W3C

  • Draf Kerja: diterbitkan untuk ditinjau oleh komunitas

Dukungan Peramban

Google Chrome Microsoft Edge Peramban Opera Firefox Safari
Didukung Didukung Didukung Tidak didukung Dukungan sebagian (*)

* didukung dengan "fitur Platform Web Eksperimental" atau tanda fitur lain yang diaktifkan.

Sumber data: Apakah Houdini Sudah Siap?

Properti Kustom Dan Nilai API

CSS Properties And Values ​​API memungkinkan pengembang untuk memperluas variabel CSS dengan menambahkan tipe, nilai awal, dan menentukan pewarisan. Pengembang dapat menentukan properti kustom CSS dengan mendaftarkannya menggunakan metode registerProperty yang memberi tahu browser cara mentransisikannya dan menangani fallback jika terjadi kesalahan.

 CSS.registerProperty({ name: "--colorPrimary", syntax: "<color>", inherits: false, initialValue: "blue", });

Metode ini menerima argumen input yang merupakan objek dengan properti berikut:

  • name : nama properti khusus
  • syntax : memberi tahu browser cara mengurai properti khusus. Ini adalah nilai yang telah ditentukan sebelumnya seperti <color> , <integer> , <number> , <length> , <percentage> , dll.
  • inherits : memberitahu browser apakah properti kustom mewarisi nilai induknya.
  • initialValue : memberi tahu nilai awal yang digunakan hingga diganti dan ini digunakan sebagai cadangan jika terjadi kesalahan.

Dalam contoh berikut, properti kustom tipe <color> sedang disetel. Properti kustom ini akan digunakan dalam transisi gradien. Anda mungkin berpikir bahwa CSS saat ini tidak mendukung transisi untuk gradien latar belakang dan Anda benar. Perhatikan bagaimana properti kustom itu sendiri digunakan dalam transition , alih-alih properti background yang akan digunakan untuk transisi background-color biasa.

 .gradientBox { background: linear-gradient(45deg, rgba(255,255,255,1) 0%, var(--colorPrimary) 60%); transition: --colorPrimary 0.5s ease; /* ... */ } .gradientBox:hover { --colorPrimary: red /* ... */ }

Browser tidak tahu bagaimana menangani transisi gradien, tetapi tahu bagaimana menangani transisi warna karena properti kustom ditentukan sebagai tipe <color> . Pada browser yang mendukung Houdini, transisi gradien akan terjadi saat elemen diarahkan. Persentase posisi gradien juga dapat diganti dengan properti kustom CSS (terdaftar sebagai tipe <percentage> ) dan ditambahkan ke transisi dengan cara yang sama seperti pada contoh.

Jika registerProperty dihapus dan properti kustom CSS biasa didaftarkan di pemilih :root , transisi gradien tidak akan berfungsi. registerProperty diperlukan agar browser mengetahui bahwa ia harus memperlakukannya sebagai warna.

Dalam implementasi API ini di masa mendatang, dimungkinkan untuk mendaftarkan properti khusus secara langsung di CSS.

 @property --colorPrimary { syntax: "<color>"; inherits: false; initial-value: blue; }

Contoh

Contoh sederhana ini menampilkan transisi warna dan posisi gradien pada acara hover menggunakan properti kustom CSS terdaftar untuk warna dan posisi masing-masing. Kode sumber lengkap tersedia di repositori contoh.

Warna dan posisi gradien animasi menggunakan Custom Properties & Values ​​API. Penundaan untuk setiap properti ditambahkan untuk efek di properti transisi CSS. (Pratinjau besar)

Deteksi Fitur

 if (CSS.registerProperty) { /* ... */ }

Status Spesifikasi W3C

  • Draf Kerja: diterbitkan untuk ditinjau oleh komunitas

Dukungan Peramban

Google Chrome Microsoft Edge Peramban Opera Firefox Safari
Didukung Didukung Didukung Tidak didukung Tidak didukung

Sumber data: Apakah Houdini Sudah Siap?

API Metrik Font

Font Metrics API masih dalam tahap pengembangan yang sangat awal, sehingga spesifikasinya dapat berubah di masa mendatang. Dalam drafnya saat ini, Font Metrics API akan menyediakan metode untuk mengukur dimensi elemen teks yang dirender di layar untuk memungkinkan pengembang memengaruhi cara elemen teks dirender di layar. Nilai-nilai ini sulit atau tidak mungkin diukur dengan fitur saat ini, jadi API ini akan memungkinkan pengembang membuat fitur CSS terkait teks dan font dengan lebih mudah. Pemotongan teks dinamis multi-baris adalah contoh dari salah satu fitur tersebut.

Status Spesifikasi W3C

  • Kumpulan Ide: tidak ada draf spesifikasi yang diajukan saat ini

Dukungan Peramban

Google Chrome Microsoft Edge Peramban Opera Firefox Safari
Tidak didukung Tidak didukung Tidak didukung Tidak didukung Tidak didukung

Sumber data: Apakah Houdini Sudah Siap?

Worklet

Sebelum pindah ke API lain, penting untuk menjelaskan konsep Worklet. Worklet adalah skrip yang berjalan selama render dan tidak bergantung pada lingkungan JavaScript utama. Mereka adalah titik ekstensi untuk mesin rendering. Mereka dirancang untuk paralelisme (dengan 2 atau lebih instance) dan thread-agnostik, telah mengurangi akses ke lingkup global dan dipanggil oleh mesin rendering bila diperlukan. Worklet hanya dapat dijalankan di HTTPS (di lingkungan produksi) atau di localhost (untuk tujuan pengembangan).

Houdini memperkenalkan Worklet berikut untuk memperluas mesin render browser:

  • Worklet Cat - API Cat
  • Worklet Animasi - API Animasi
  • Layout Worklet - Layout API

API Cat

API Paint memungkinkan pengembang menggunakan fungsi JavaScript untuk menggambar langsung ke latar belakang, batas, atau konten elemen menggunakan Konteks Rendering 2D, yang merupakan subset dari API Kanvas HTML5. Paint API menggunakan Paint Worklet untuk menggambar gambar yang secara dinamis merespons perubahan CSS (perubahan dalam variabel CSS, misalnya). Siapa pun yang akrab dengan Canvas API akan merasa betah dengan Paint API Houdini.

Ada beberapa langkah yang diperlukan dalam mendefinisikan Paint Worklet:

  1. Tulis dan daftarkan Worklet Paint menggunakan fungsi registerPaint
  2. Panggil Worklet dalam file HTML atau file JavaScript utama menggunakan fungsi CSS.paintWorklet.addModule
  3. Gunakan fungsi paint() di CSS dengan nama Worklet dan argumen input opsional.

Mari kita lihat fungsi registerPaint yang digunakan untuk mendaftarkan Paint Worklet dan mendefinisikan fungsinya.

 registerPaint("paintWorketExample", class { static get inputProperties() { return ["--myVariable"]; } static get inputArguments() { return ["<color>"]; } static get contextOptions() { return {alpha: true}; } paint(ctx, size, properties, args) { /* ... */ } });

Fungsi registerPaint terdiri dari beberapa bagian:

  • inputProperties :
    Array properti kustom CSS yang akan dilacak oleh Worklet. Array ini mewakili dependensi worklet cat.
  • inputArguments :
    Array argumen input yang dapat diteruskan dari fungsi paint dari dalam CSS.
  • contextOptions : mengizinkan atau melarang opacity untuk warna. Jika disetel ke false , semua warna akan ditampilkan dengan opacity penuh.
  • paint : fungsi utama yang menyediakan argumen berikut:
    • ctx : konteks gambar 2D, hampir identik dengan konteks gambar 2D Canvas API.
    • size : objek yang memuat lebar dan tinggi elemen. Nilai ditentukan oleh proses rendering tata letak. Ukuran kanvas sama dengan ukuran sebenarnya dari elemen.
    • properties : variabel input yang didefinisikan di inputProperties
    • args : array argumen input yang diteruskan dalam fungsi paint di CSS

Setelah Worklet didaftarkan, itu perlu dipanggil dalam file HTML hanya dengan menyediakan jalur ke file.

 CSS.paintWorklet.addModule("path/to/worklet/file.js");

Worklet apa pun juga dapat ditambahkan dari URL eksternal (dari Jaringan Pengiriman Konten, misalnya) yang menjadikannya modular dan dapat digunakan kembali.

 CSS.paintWorklet.addModule("https://url/to/worklet/file.js");

Setelah Worklet dipanggil, Worklet dapat digunakan di dalam CSS menggunakan fungsi paint . Fungsi ini menerima nama terdaftar Worklet sebagai argumen input pertama dan setiap argumen input yang mengikutinya adalah argumen khusus yang dapat diteruskan ke Worklet (didefinisikan di dalam inputArguments inputArguments ). Sejak saat itu, browser menentukan kapan harus memanggil Worklet dan tindakan pengguna dan nilai properti kustom CSS mana yang berubah untuk ditanggapi.

 .exampleElement { /* paintWorkletExample - name of the worklet blue - argument passed to a Worklet */ background-image: paint(paintWorketExample, blue); }

Contoh

Contoh berikut menampilkan API Paint dan kegunaan umum serta modularitas Worklet. Ini menggunakan Worklet riak langsung dari repositori Google Chrome Labs dan berjalan pada elemen yang berbeda dengan gaya yang berbeda. Kode sumber lengkap tersedia di repositori contoh.

Contoh efek riak (menggunakan Ripple Worklet oleh Google Chrome Labs) (Pratinjau besar)

Deteksi fitur

 if ("paintWorklet" in CSS) { /* ... */ } @supports(background:paint(paintWorketExample)){ /* ... */ }

Status Spesifikasi W3C

  • Rekomendasi kandidat: draft kerja yang stabil siap untuk diimplementasikan

Dukungan Peramban

Google Chrome Microsoft Edge Peramban Opera Firefox Safari
Didukung Didukung Didukung Tidak didukung Tidak didukung

Sumber data: Apakah Houdini Sudah Siap?

API Animasi

Animation API memperluas animasi web dengan opsi untuk mendengarkan berbagai peristiwa (gulir, arahkan kursor, klik, dll.) dan meningkatkan kinerja dengan menjalankan animasi pada utas khusus mereka sendiri menggunakan Worklet Animasi. Ini memungkinkan tindakan pengguna untuk mengontrol aliran animasi yang berjalan dengan cara yang berkinerja dan tidak memblokir.

Seperti Worklet lainnya, Animation Worklet harus didaftarkan terlebih dahulu.

 registerAnimator("animationWorkletExample", class { constructor(options) { /* ... */ } animate(currentTime, effect) { /* ... */ } });

Kelas ini terdiri dari dua fungsi:

  • constructor : dipanggil saat instance baru dibuat. Digunakan untuk pengaturan umum.
  • animate : fungsi utama yang berisi logika animasi. Memberikan argumen masukan berikut:
    • currentTime : nilai waktu saat ini dari garis waktu yang ditentukan
    • effect : serangkaian efek yang digunakan animasi ini

Setelah Animation Worklet didaftarkan, ia perlu dimasukkan ke dalam file JavaScript utama , animasi (element, keyframes, options) perlu ditentukan dan animasi dibuat dengan timeline yang dipilih. Konsep timeline dan dasar-dasar animasi web akan dijelaskan di bagian selanjutnya.

 /* Include Animation Worklet */ await CSS.animationWorklet.addModule("path/to/worklet/file.js");; /* Select element that's going to be animated */ const elementExample = document.getElementById("elementExample"); /* Define animation (effect) */ const effectExample = new KeyframeEffect( elementExample, /* Selected element that's going to be animated */ [ /* ... */ ], /* Animation keyframes */ { /* ... */ }, /* Animation options - duration, delay, iterations, etc. */ ); /* Create new WorkletAnimation instance and run it */ new WorkletAnimation( "animationWorkletExample" /* Worklet name */ effectExample, /* Animation (effect) timeline */ document.timeline, /* Input timeline */ {}, /* Options passed to constructor */ ).play(); /* Play animation */

Pemetaan Garis Waktu

Animasi web didasarkan pada garis waktu dan pemetaan waktu saat ini ke garis waktu waktu lokal efek . Sebagai contoh, mari kita lihat animasi linier berulang dengan 3 keyframe (mulai, tengah, terakhir) yang berjalan 1 detik setelah halaman dimuat (penundaan) dan dengan durasi 4 detik.

Garis waktu efek dari contoh akan terlihat seperti ini (dengan durasi 4 detik tanpa penundaan):

Garis waktu efek (durasi 4 detik) Bingkai utama
0ms Bingkai utama pertama - animasi dimulai
2000ms Bingkai utama tengah - animasi sedang berlangsung
4000ms Bingkai utama terakhir - animasi berakhir atau disetel ulang ke bingkai utama pertama

Untuk lebih memahami effect.localTime , dengan menyetel nilainya ke 3000ms (dengan memperhitungkan penundaan 1000ms), animasi yang dihasilkan akan dikunci ke bingkai utama tengah di timeline efek (penundaan 1000ms + 2000ms untuk bingkai utama tengah). Efek yang sama akan terjadi dengan mengatur nilainya menjadi 7000ms dan 11000ms karena animasi berulang dalam interval 4000ms (durasi animasi).

 animate(currentTime, effect) { effect.localTime = 3000; // 1000ms delay + 2000ms middle keyframe }

Tidak ada animasi yang terjadi saat memiliki nilai effect.localTime yang konstan karena animasi dikunci dalam bingkai utama tertentu. Untuk menganimasikan elemen dengan benar, effect.localTime -nya harus dinamis. Ini diperlukan agar nilai menjadi fungsi yang bergantung pada argumen input currentTime atau beberapa variabel lainnya.

Kode berikut menunjukkan representasi fungsional pemetaan 1:1 (fungsi linier) dari garis waktu untuk mempengaruhi waktu setempat.

 animate(currentTime, effect) { effect.localTime = currentTime; // y = x linear function }
Garis waktu ( document.timeline ) Efek yang dipetakan waktu setempat Bingkai utama
startTime + 0ms (waktu yang berlalu) waktu mulai + startTime Pertama
startTime + 1000ms (waktu yang berlalu) waktu startTime md (penundaan) + 0 md Pertama
startTime + 3000ms (waktu yang berlalu) waktu startTime md (penundaan) + 2000 md Tengah
startTime + 5000ms (waktu yang berlalu) waktu startTime + 1000 md (penundaan) + 4000 md Terakhir / Pertama
startTime + 7000ms (waktu yang berlalu) waktu startTime + 1000 md (penundaan) + 6000 md Tengah
startTime + 9000ms (waktu yang berlalu) waktu startTime + 1000 md (penundaan) + 8000 md Terakhir / Pertama

Garis waktu tidak terbatas pada pemetaan 1:1 untuk mempengaruhi waktu lokal. Animation API memungkinkan pengembang untuk memanipulasi pemetaan garis waktu dalam fungsi animate dengan menggunakan fungsi JavaScript standar untuk membuat garis waktu yang kompleks. Animasi juga tidak harus berperilaku sama di setiap iterasi (jika animasi diulang).

Animasi tidak harus bergantung pada garis waktu dokumen yang hanya mulai menghitung milidetik sejak dimuat. Tindakan pengguna seperti peristiwa gulir dapat digunakan sebagai garis waktu untuk animasi dengan menggunakan objek ScrollTimeline . Misalnya, animasi dapat dimulai ketika pengguna telah menggulir ke 200 piksel dan dapat berakhir ketika pengguna telah menggulir ke 800 piksel di layar.

 const scrollTimelineExample = new ScrollTimeline({ scrollSource: scrollElement, /* DOM element whose scrolling action is being tracked */ orientation: "vertical", /* Scroll direction */ startScrollOffset: "200px", /* Beginning of the scroll timeline */ endScrollOffset: "800px", /* Ending of the scroll timeline */ timeRange: 1200, /* Time duration to be mapped to scroll values*/ fill: "forwards" /* Animation fill mode */ }); ...

Animasi akan secara otomatis beradaptasi dengan kecepatan gulir pengguna dan tetap halus dan responsif. Karena Animation Worklet menjalankan thread utama dan terhubung ke mesin rendering browser, animasi yang bergantung pada scroll pengguna dapat berjalan dengan lancar dan sangat berkinerja.

Contoh

Contoh berikut menunjukkan bagaimana implementasi timeline non-linear. Ini menggunakan fungsi Gaussian yang dimodifikasi dan menerapkan animasi terjemahan dan rotasi dengan garis waktu yang sama. Kode sumber lengkap tersedia di repositori contoh.

Animasi dibuat dengan Animation API yang menggunakan pemetaan waktu fungsi Gaussian yang dimodifikasi (Pratinjau besar)

Deteksi Fitur

 if (CSS.animationWorklet) { /* ... */ }

Status Spesifikasi W3C

  • Draft Pekerjaan Umum Pertama: siap untuk tinjauan masyarakat, rentan terhadap perubahan spesifikasi

Dukungan Peramban

Google Chrome Microsoft Edge Peramban Opera Firefox Safari
Dukungan sebagian (*) Dukungan sebagian (*) Dukungan sebagian (*) Tidak didukung Tidak didukung

* didukung dengan tanda "Fitur Platform Web Eksperimental" diaktifkan.

Sumber data: Apakah Houdini Sudah Siap?

API Tata Letak

Layout API memungkinkan pengembang untuk memperluas proses rendering tata letak browser dengan menentukan mode tata letak baru yang dapat digunakan dalam properti CSS display . Layout API memperkenalkan konsep baru, sangat kompleks dan menawarkan banyak opsi untuk mengembangkan algoritme tata letak khusus.

Sama halnya dengan Worklet lainnya, Worklet layout perlu didaftarkan dan didefinisikan terlebih dahulu.

 registerLayout('exampleLayout', class { static get inputProperties() { return ['--exampleVariable']; } static get childrenInputProperties() { return ['--exampleChildVariable']; } static get layoutOptions() { return { childDisplay: 'normal', sizing: 'block-like' }; } intrinsicSizes(children, edges, styleMap) { /* ... */ } layout(children, edges, constraints, styleMap, breakToken) { /* ... */ } });

Register worklet berisi metode berikut:

  • inputProperties :
    Larik properti kustom CSS yang akan dilacak oleh Worklet yang dimiliki oleh elemen Tata Letak Induk, yaitu elemen yang memanggil tata letak ini. Array ini mewakili dependensi dari Layout Worklet.
  • childrenInputProperties :
    Larik properti kustom CSS yang akan dilacak oleh Worklet yang dimiliki oleh elemen turunan dari elemen Tata Letak Induk, yaitu turunan dari elemen yang menyetel tata letak ini.
  • layoutOptions : mendefinisikan properti layout berikut:
    • childDisplay : dapat memiliki nilai block atau normal yang telah ditentukan sebelumnya. Menentukan apakah kotak akan ditampilkan sebagai blok atau sebaris.
    • sizing : dapat memiliki nilai block-like atau manual yang telah ditentukan sebelumnya. Ini memberi tahu browser untuk menghitung sebelumnya ukuran atau tidak menghitung sebelumnya (kecuali jika ukuran diatur secara eksplisit), masing-masing.
  • intrinsicSizes : mendefinisikan bagaimana kotak atau isinya cocok dengan konteks tata letak.
    • children : elemen anak dari elemen Tata Letak Induk, yaitu anak dari elemen yang memanggil tata letak ini.
    • edges : Tata Letak Tepi kotak
    • styleMap : mengetik gaya OM dari sebuah kotak
  • layout : fungsi utama yang melakukan layout.
    • children : elemen anak dari elemen Tata Letak Induk, yaitu anak dari elemen yang memanggil tata letak ini.
    • edges : Tata Letak Tepi kotak
    • constraints : kendala Layout Induk
    • styleMap : mengetik gaya OM dari sebuah kotak
    • breakToken : break token yang digunakan untuk melanjutkan tata letak jika ada pagination atau pencetakan.

Seperti dalam kasus Paint API, mesin rendering browser menentukan kapan Paint Worklet dipanggil. Itu hanya perlu ditambahkan ke file HTML atau JavaScript utama.

 CSS.layoutWorklet.addModule('path/to/worklet/file.js');

Dan, akhirnya, itu perlu direferensikan dalam file CSS

 .exampleElement { display: layout(exampleLayout); }

Bagaimana Layout API Melakukan Layout

Pada contoh sebelumnya, exampleLayout telah didefinisikan menggunakan Layout API.

 .exampleElement { display: layout(exampleLayout); }

Elemen ini disebut Layout Induk yang diapit dengan Layout Edges yang terdiri dari padding, border, dan scroll bar. Tata Letak Induk terdiri dari elemen anak yang disebut Tata Letak Saat Ini . Tata Letak Saat Ini adalah elemen target aktual yang tata letaknya dapat dikustomisasi menggunakan Layout API. Misalnya, saat menggunakan display: flex; pada sebuah elemen, anak-anaknya sedang diposisikan ulang untuk membentuk tata letak fleksibel. Ini mirip dengan apa yang dilakukan dengan Layout API.

Setiap Tata Letak Saat Ini terdiri dari Tata Letak Anak yang merupakan algoritme tata letak untuk LayoutChild (elemen, ::before dan ::after elemen semu) dan LayoutChild adalah kotak yang dihasilkan CSS yang hanya berisi data gaya (tidak ada data tata letak). Elemen LayoutChild secara otomatis dibuat oleh mesin rendering browser pada langkah gaya. Layout Child dapat menghasilkan Fragmen yang benar-benar melakukan tindakan render tata letak.

Contoh

Serupa dengan contoh Paint API, contoh ini mengimpor Worklet tata letak batu langsung dari repositori Google Chrome Labs, tetapi dalam contoh ini, digunakan dengan konten gambar, bukan teks. Kode sumber lengkap tersedia di repositori contoh.

Contoh tata letak Masonry (menggunakan Masonry Worklet oleh Google Chrome Labs (Pratinjau besar)

Deteksi Fitur

 if (CSS.layoutWorklet) { /* ... */ }

Status Spesifikasi W3C

  • Draft Pekerjaan Umum Pertama: siap untuk tinjauan masyarakat, rentan terhadap perubahan spesifikasi

Dukungan Peramban

Google Chrome Microsoft Edge Peramban Opera Firefox Safari
Dukungan sebagian (*) Dukungan sebagian (*) Dukungan sebagian (*) Tidak didukung Tidak didukung

* didukung dengan tanda "Fitur Platform Web Eksperimental" diaktifkan.

Sumber data: Apakah Houdini Sudah Siap?

Houdini Dan Peningkatan Progresif

Meskipun CSS Houdini belum memiliki dukungan browser yang optimal, CSS Houdini dapat digunakan saat ini dengan mempertimbangkan peningkatan progresif. Jika Anda tidak terbiasa dengan peningkatan Progresif, ada baiknya membaca artikel praktis ini yang menjelaskannya dengan sangat baik. Jika Anda memutuskan untuk menerapkan Houdini dalam proyek Anda hari ini, ada beberapa hal yang perlu diingat:

  • Gunakan deteksi fitur untuk mencegah kesalahan.
    Setiap Houdini API dan Worklet menawarkan cara sederhana untuk memeriksa apakah tersedia di browser. Gunakan deteksi fitur untuk menerapkan peningkatan Houdini hanya ke browser yang mendukungnya dan menghindari kesalahan.
  • Gunakan untuk presentasi dan peningkatan visual saja.
    Pengguna yang menjelajahi situs web di browser yang belum mendukung Houdini harus memiliki akses ke konten dan fungsionalitas inti situs web. Pengalaman pengguna dan presentasi konten tidak boleh bergantung pada fitur Houdini dan harus memiliki cadangan yang andal.
  • Manfaatkan fallback CSS standar.
    Misalnya, CSS Custom Properties biasa dapat digunakan sebagai fallback untuk gaya yang ditentukan menggunakan Custom Properties & Values ​​API.

Fokus pada pengembangan pengalaman pengguna situs web yang berkinerja dan andal terlebih dahulu, lalu gunakan fitur Houdini untuk tujuan dekoratif sebagai peningkatan progresif.

Kesimpulan

API Houdini akhirnya akan memungkinkan pengembang untuk menjaga kode JavaScript yang digunakan untuk manipulasi gaya dan dekorasi lebih dekat ke saluran rendering browser, menghasilkan kinerja dan stabilitas yang lebih baik. Dengan mengizinkan pengembang untuk terhubung ke proses rendering browser, mereka akan dapat mengembangkan berbagai polyfill CSS yang dapat dengan mudah dibagikan, diimplementasikan, dan, berpotensi, ditambahkan ke spesifikasi CSS itu sendiri. Houdini juga akan membuat pengembang dan desainer tidak terlalu dibatasi oleh batasan CSS saat mengerjakan gaya, tata letak, dan animasi, sehingga menghasilkan pengalaman web baru yang menyenangkan.

Fitur CSS Houdini dapat ditambahkan ke proyek hari ini, tetapi secara ketat dengan peningkatan progresif dalam pikiran. Ini akan memungkinkan browser yang tidak mendukung fitur Houdini untuk membuat situs web tanpa kesalahan dan menawarkan pengalaman pengguna yang optimal.

Akan sangat menarik untuk melihat apa yang akan muncul dari komunitas pengembang saat Houdini mendapatkan daya tarik dan dukungan browser yang lebih baik. Berikut adalah beberapa contoh luar biasa dari eksperimen Houdini API dari komunitas:

  • Eksperimen CSS Houdini
  • Pengenalan Interaktif CSS Houdini
  • Sampel Houdini oleh Google Chrome Labs

Referensi

  • Draf Spesifikasi W3C Houdini
  • Negara Bagian Houdini (Chrome Dev Summit 2018)
  • Worklet Animasi Houdini - Pengembang Google
  • Pengenalan Interaktif CSS Houdini