Ikhtisar Praktis CSS Houdini
Diterbitkan: 2022-03-10Perlu 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.
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.
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:
- Tulis dan daftarkan Worklet Paint menggunakan fungsi
registerPaint
- Panggil Worklet dalam file HTML atau file JavaScript utama menggunakan fungsi
CSS.paintWorklet.addModule
- 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 fungsipaint
dari dalam CSS. -
contextOptions
: mengizinkan atau melarang opacity untuk warna. Jika disetel kefalse
, 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 diinputProperties
-
args
: array argumen input yang diteruskan dalam fungsipaint
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.
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.
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 nilaiblock
ataunormal
yang telah ditentukan sebelumnya. Menentukan apakah kotak akan ditampilkan sebagai blok atau sebaris. -
sizing
: dapat memiliki nilaiblock-like
ataumanual
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.
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