CSS Houdini'ye Pratik Bir Bakış
Yayınlanan: 2022-03-10Yeni bir CSS özelliğinin veya iyileştirmesinin ilk taslaktan geliştiricilerin kullanabileceği tam olarak desteklenen ve kararlı bir CSS özelliğine geçmesi uzun zaman alır. JavaScript tabanlı çoklu dolgular, resmi olarak uygulanmadan önce yeni CSS özelliklerini kullanmak için tarayıcı desteği eksikliğinin yerine kullanılabilir. Ancak çoğu durumda kusurludurlar. Örneğin scrollsnap-polyfill, CSS Scroll Snap spesifikasyonu için tarayıcı desteği tutarsızlıklarını düzeltmek için kullanılabilecek birkaç çoklu dolgudan biridir. Ancak bu çözümün bile bazı sınırlamaları, hataları ve tutarsızlıkları vardır.
Çoklu dolgu kullanmanın potansiyel dezavantajı, performans üzerinde olumsuz bir etkiye sahip olabilmeleri ve düzgün bir şekilde uygulanmasının zor olmasıdır. Bu dezavantaj, tarayıcının DOM ve CSSOM'si ile ilgilidir. Tarayıcı, HTML işaretlemesinden bir DOM (Belge Nesne Modeli) oluşturur ve benzer şekilde CSS işaretlemesinden CSSOM (CSS Nesne Modeli) oluşturur. Bu iki nesne ağacı birbirinden bağımsızdır. JavaScript, DOM üzerinde çalışır ve CSSOM'a çok sınırlı erişime sahiptir.
JavaScript Polyfill çözümleri, yalnızca ilk oluşturma döngüsü tamamlandıktan sonra, yani hem DOM hem de CSSOM oluşturulduğunda ve belgenin yüklenmesi tamamlandığında çalışır. Polyfill, DOM'deki stillerde değişiklik yaptıktan sonra (bunları satır içine alarak), oluşturma işleminin yeniden çalışmasına ve tüm sayfanın yeniden oluşturulmasına neden olur. Olumsuz performans etkisi, requestAnimationFrame
yöntemine güveniyorsa veya kaydırma olayları gibi kullanıcı etkileşimlerine bağlıysa daha da belirginleşir.
Web geliştirmedeki diğer bir engel de CSS standartlarının dayattığı çeşitli kısıtlamalardır . Örneğin, yerel olarak canlandırılabilen yalnızca sınırlı sayıda CSS özelliği vardır. CSS, renkleri doğal olarak nasıl canlandıracağını bilir, ancak degradeleri nasıl canlandıracağını bilmez. Teknolojik sınırlamalara rağmen sınırları zorlayarak yenilik yapmaya ve etkileyici web deneyimleri yaratmaya her zaman ihtiyaç duyulmuştur. Bu nedenle geliştiriciler, duvar düzeni, gelişmiş 3B efektler, gelişmiş animasyon, akıcı tipografi, animasyonlu degradeler, tarz select
elemanları, vb.
Animasyonlar üzerinde daha fazla kontrol, geliştirilmiş metin kesme, input
ve select
öğeleri için daha iyi stil seçeneği, daha fazla display
seçeneği, daha fazla filter
seçeneği vb. gibi endüstriden gelen çeşitli özellik taleplerini karşılaması CSS spesifikasyonları için imkansız görünüyor.
Potansiyel çözüm ne olabilir? Geliştiricilere çeşitli API'leri kullanarak CSS'yi genişletmenin yerel bir yolunu verin. Bu makalede, ön uç geliştiricilerin Houdini API'lerini, JavaScript'i ve CSS'yi kullanarak bunu nasıl yapabileceğine bir göz atacağız. Her bölümde, her API'yi ayrı ayrı inceleyeceğiz, tarayıcı desteğini ve mevcut spesifikasyon durumunu kontrol edeceğiz ve Aşamalı geliştirme kullanılarak bugün nasıl uygulanabileceklerini göreceğiz.
Houdini Nedir?
Tarayıcı API'lerinin toplanması için bir şemsiye terim olan Houdini, web geliştirme sürecine ve genel olarak CSS standartlarının geliştirilmesine önemli iyileştirmeler getirmeyi amaçlamaktadır. Geliştiriciler, JavaScript kullanarak CSS'yi yeni özelliklerle genişletebilecek, CSS oluşturma motoruna bağlanabilecek ve tarayıcıya bir oluşturma işlemi sırasında CSS'nin nasıl uygulanacağını söyleyebilecek. Bu, normal çoklu dolguların kullanılmasından önemli ölçüde daha iyi performans ve stabilite ile sonuçlanacaktır.
Houdini spesifikasyonu iki API grubundan oluşur - yüksek seviyeli API'ler ve düşük seviyeli API'ler .
Üst düzey API'ler , tarayıcının oluşturma süreciyle yakından ilişkilidir (stil → düzen → boya → bileşik). Bu içerir:
- Boya API'sı
Görsel özelliklerin (renk, arka plan, kenarlık vb.) belirlendiği tarayıcının boya oluşturma adımı için bir uzantı noktası. - Düzen API'si
Öğe boyutlarının, konumun ve hizalamanın belirlendiği tarayıcının yerleşim oluşturma adımı için bir uzantı noktası. - Animasyon API'si
Katmanların ekrana çizildiği ve canlandırıldığı tarayıcının bileşik oluşturma adımı için bir uzantı noktası.
Düşük Seviyeli API'ler, yüksek seviyeli API'ler için bir temel oluşturur. Bu içerir:
- Yazılan Nesne Modeli API'si
- Özel Özellikler ve Değerler API'sı
- Yazı Tipi Metrikleri API'sı
- İşletler
Bazı Houdini API'leri, yayınlanmaya hazır olduklarında buna uymak için bazı tarayıcılarda diğer API'lerle birlikte kullanım için zaten mevcuttur.
CSS'nin Geleceği
Şimdiye kadar tanıtılan normal CSS özellik özelliklerinin aksine, Houdini, geliştiricilerin CSS'yi daha yerel bir şekilde genişletmesine izin vererek öne çıkıyor. Bu, CSS özelliklerinin gelişmeyi durduracağı ve CSS özelliklerinin yeni resmi uygulamalarının yayınlanmayacağı anlamına mı geliyor? Peki, durum böyle değil. Houdini'nin amacı, geliştiricilerin kolayca standartlaştırılabilen çalışma prototipleri oluşturmasına olanak tanıyarak CSS özellik geliştirme sürecine yardımcı olmaktır.
Ek olarak, geliştiriciler açık kaynaklı CSS Çalışma Uygulamalarını daha kolay ve tarayıcıya özel hata düzeltmelerine daha az ihtiyaç duyarak paylaşabilecekler.
Yazılan Nesne Modeli API'si
Houdini tanıtılmadan önce, JavaScript'in CSS ile etkileşime girmesinin tek yolu, dize değerleri olarak temsil edilen CSS'yi ayrıştırmak ve bunları değiştirmekti. Stilleri manuel olarak ayrıştırmak ve geçersiz kılmak, değer türünün ileri geri değiştirilmesi gerektiğinden ve yeni bir değer atanırken değer biriminin manuel olarak eklenmesi gerektiğinden zor ve hataya açık olabilir.
selectedElement.style.fontSize = newFontSize + "px"; // newFontSize = 20 console.log(selectedElement.style.fontSize); // "20px"
Yazılan Nesne Modeli (Yazılan OM) API'si, CSS değerlerini yazılan JavaScript nesneleri olarak göstererek onlara daha fazla anlamsal anlam katar. İlgili kodu önemli ölçüde iyileştirir ve daha performanslı, kararlı ve sürdürülebilir hale getirir. CSS değerleri, bir değer ve bir birim özelliğinden oluşan CSSUnitValue
arabirimi tarafından temsil edilir.
{ value: 20, unit: "px" }
Bu yeni arayüz aşağıdaki yeni özelliklerle kullanılabilir:
-
computedStyleMap()
: hesaplanmış (satır içi olmayan) stilleri ayrıştırmak için. Bu, ayrıştırılmadan veya diğer yöntemler kullanılmadan önce çağrılması gereken seçili öğe yöntemidir. -
attributeStyleMap
: satır içi stilleri ayrıştırmak ve değiştirmek için. Bu, seçili bir öğede kullanılabilen bir özelliktir.
// 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"}
Yeni bir sayısal değer ayarlarken belirli CSS türlerinin nasıl kullanıldığına dikkat edin. Bu söz dizimini kullanarak, türle ilgili birçok olası sorundan kaçınılabilir ve sonuçta ortaya çıkan kod daha güvenilir ve hatasız olur.
get
ve set
yöntemleri, Typed OM API tarafından tanımlanan tüm kullanılabilir yöntemlerin yalnızca küçük bir alt kümesidir. Bazıları şunları içerir:
-
clear
: tüm satır içi stilleri kaldırır -
delete
: belirtilen bir CSS özelliğini ve değerini satır içi stillerden kaldırır -
has
: belirtilen bir CSS özelliği ayarlanmışsa bir boole döndürür -
append
: birden çok değeri destekleyen bir özelliğe ek bir değer ekler - vb.
Özellik algılama
var selectedElement = document.getElementById("example"); if(selectedElement.attributeStyleMap) { /* ... */ } if(selectedElement.computedStyleMap) { /* ... */ }
W3C Spesifikasyon Durumu
- Çalışma Taslağı: topluluk tarafından incelenmek üzere yayınlandı
Tarayıcı Desteği
Google Chrome | Microsoft Kenarı | Opera Tarayıcı | Firefox | Safari |
---|---|---|---|---|
Desteklenen | Desteklenen | Desteklenen | Desteklenmiyor | Kısmi destek (*) |
* “Deneysel Web Platformu özellikleri” ile desteklenir veya diğer özellik bayrağı etkinleştirilir.
Veri kaynağı: Houdini Henüz Hazır mı?
Özel Özellikler ve Değerler API'sı
CSS Özellikleri ve Değerleri API'si, geliştiricilerin bir tür, başlangıç değeri ekleyerek ve kalıtımı tanımlayarak CSS değişkenlerini genişletmesine olanak tanır. Geliştiriciler, tarayıcılara nasıl geçiş yapılacağını ve bir hata durumunda yedeği nasıl işleyeceğini söyleyen registerProperty
yöntemini kullanarak bunları kaydederek CSS özel özelliklerini tanımlayabilir.
CSS.registerProperty({ name: "--colorPrimary", syntax: "<color>", inherits: false, initialValue: "blue", });
Bu yöntem, aşağıdaki özelliklere sahip bir nesne olan bir girdi bağımsız değişkenini kabul eder:
-
name
: özel mülkün adı -
syntax
: tarayıcıya özel bir özelliğin nasıl ayrıştırılacağını söyler. Bunlar,<color>
,<integer>
,<number>
,<length>
,<percentage>
vb. gibi önceden tanımlanmış değerlerdir. -
inherits
: tarayıcıya, özel özelliğin üst öğesinin değerini devralıp devralmadığını söyler. -
initialValue
: geçersiz kılınana kadar kullanılan başlangıç değerini söyler ve bu, bir hata durumunda geri dönüş olarak kullanılır.
Aşağıdaki örnekte, <color>
tipi özel özellik ayarlanıyor. Bu özel özellik, degrade geçişinde kullanılacaktır. Mevcut CSS'nin arka plan geçişleri için geçişleri desteklemediğini düşünüyor olabilirsiniz ve haklısınız. Normal background-color
geçişleri için kullanılacak bir background
özelliği yerine, özel özelliğin kendisinin transition
nasıl kullanıldığına dikkat edin.
.gradientBox { background: linear-gradient(45deg, rgba(255,255,255,1) 0%, var(--colorPrimary) 60%); transition: --colorPrimary 0.5s ease; /* ... */ } .gradientBox:hover { --colorPrimary: red /* ... */ }
Tarayıcı, degrade geçişini nasıl işleyeceğini bilmiyor, ancak özel özellik <color>
türü olarak belirtildiği için renk geçişlerini nasıl işleyeceğini biliyor. Houdini'yi destekleyen bir tarayıcıda, öğenin üzerine gelindiğinde bir degrade geçişi gerçekleşir. Gradyan konumu yüzdesi ayrıca CSS özel özelliğiyle ( <percentage>
türü olarak kaydedilir) değiştirilebilir ve örnekte olduğu gibi bir geçişe eklenebilir.
registerProperty
kaldırılırsa ve bir :root
seçiciye normal bir CSS özel özelliği kaydedilirse, degrade geçişi çalışmaz. Tarayıcının onu renk olarak ele alması gerektiğini bilmesi için registerProperty
öğesinin kullanılması gerekir.
Bu API'nin gelecekteki uygulamasında, özel bir özelliği doğrudan CSS'ye kaydetmek mümkün olacaktır.
@property --colorPrimary { syntax: "<color>"; inherits: false; initial-value: blue; }
Örnek vermek
Bu basit örnek, sırasıyla renk ve konum için kayıtlı CSS özel özelliklerini kullanarak vurgulu olayda gradyan rengi ve konum geçişini gösterir. Örnek depoda eksiksiz kaynak kodu mevcuttur.
Özellik Algılama
if (CSS.registerProperty) { /* ... */ }
W3C Spesifikasyon Durumu
- Çalışma Taslağı: topluluk tarafından incelenmek üzere yayınlandı
Tarayıcı Desteği
Google Chrome | Microsoft Kenarı | Opera Tarayıcı | Firefox | Safari |
---|---|---|---|---|
Desteklenen | Desteklenen | Desteklenen | Desteklenmiyor | Desteklenmiyor |
Veri kaynağı: Houdini Henüz Hazır mı?
Yazı Tipi Metrikleri API'sı
Yazı Tipi Metrikleri API'si hala geliştirmenin çok erken bir aşamasındadır, bu nedenle özelliği gelecekte değişebilir. Mevcut taslağında, Font Metrics API , geliştiricilerin metin öğelerinin ekranda nasıl oluşturulduğunu etkilemesine izin vermek için ekranda oluşturulan metin öğelerinin boyutlarını ölçmek için yöntemler sağlayacaktır. Bu değerlerin mevcut özelliklerle ölçülmesi ya zor ya da imkansızdır, bu nedenle bu API, geliştiricilerin metin ve yazı tipiyle ilgili CSS özelliklerini daha kolay oluşturmasına olanak tanır. Çok satırlı dinamik metin kesme, bu özelliklerden birine bir örnektir.
W3C Spesifikasyon Durumu
- Fikirlerin Toplanması: şu anda hiçbir şartname taslağı gönderilmedi
Tarayıcı Desteği
Google Chrome | Microsoft Kenarı | Opera Tarayıcı | Firefox | Safari |
---|---|---|---|---|
Desteklenmiyor | Desteklenmiyor | Desteklenmiyor | Desteklenmiyor | Desteklenmiyor |
Veri kaynağı: Houdini Henüz Hazır mı?
İşletler
Diğer API'lere geçmeden önce Worklets kavramını açıklamak önemlidir. İşletler , oluşturma sırasında çalışan ve ana JavaScript ortamından bağımsız olan komut dosyalarıdır. Motorları işlemek için bir uzantı noktasıdır. Paralellik (2 veya daha fazla örnekle) ve iş parçacığından bağımsız olarak tasarlanmıştır, global kapsama erişimi azaltılmıştır ve gerektiğinde işleme motoru tarafından çağrılır. Worklet'ler yalnızca HTTPS'de (üretim ortamında) veya localhost'ta (geliştirme amacıyla) çalıştırılabilir.
Houdini, tarayıcı oluşturma motorunu genişletmek için aşağıdaki Worklet'leri sunar:
- Paint Worklet - Paint API
- Animasyon Çalışması - Animasyon API'sı
- Layout Worklet - Layout API
Boya API'sı
Paint API, geliştiricilerin HTML5 Canvas API'nin bir alt kümesi olan 2D Rendering Context kullanarak bir öğenin arka planına, sınırına veya içeriğine doğrudan çizim yapmak için JavaScript işlevlerini kullanmalarına olanak tanır. Paint API, CSS'deki değişikliklere (örneğin, CSS değişkenlerindeki değişiklikler) dinamik olarak yanıt veren bir görüntü çizmek için Paint Worklet'i kullanır. Canvas API'ye aşina olan herkes, Houdini'nin Paint API'si ile kendini evinde hissedecektir.
Bir Paint Worklet'i tanımlamak için gereken birkaç adım vardır:
-
registerPaint
işlevini kullanarak bir Paint Worklet yazın ve kaydedin -
CSS.paintWorklet.addModule
işlevini kullanarak Worklet'i HTML dosyasında veya ana JavaScript dosyasında çağırın - Bir Worklet adı ve isteğe bağlı giriş bağımsız değişkenleri ile CSS'de
paint()
işlevini kullanın.
Bir Paint Worklet'i kaydetmek ve işlevselliğini tanımlamak için kullanılan registerPaint
işlevine bir göz atalım.
registerPaint("paintWorketExample", class { static get inputProperties() { return ["--myVariable"]; } static get inputArguments() { return ["<color>"]; } static get contextOptions() { return {alpha: true}; } paint(ctx, size, properties, args) { /* ... */ } });
registerPaint
işlevi birkaç bölümden oluşur:
-
inputProperties
:
Worklet'in takip edeceği bir dizi CSS özel özelliği. Bu dizi, bir boyama işletinin bağımlılıklarını temsil eder. -
inputArguments
:
paint
işlevinden CSS'nin içinden iletilebilen bir dizi girdi bağımsız değişkeni. -
contextOptions
: renkler için opaklığa izin verir veya vermez.false
olarak ayarlanırsa, tüm renkler tam opaklıkla görüntülenecektir. -
paint
: aşağıdaki bağımsız değişkenleri sağlayan ana işlev:-
ctx
: 2B çizim bağlamı, Canvas API'nin 2B çizim bağlamıyla neredeyse aynı. -
size
: öğenin genişliğini ve yüksekliğini içeren bir nesne. Değerler, yerleşim oluşturma işlemi tarafından belirlenir. Tuval boyutu, öğenin gerçek boyutuyla aynıdır. -
properties
:inputProperties
tanımlanan girdi değişkenleri -
args
: CSS'dekipaint
işlevinde geçirilen bir dizi girdi bağımsız değişkeni
-
Worklet kaydedildikten sonra, dosyaya bir yol sağlayarak HTML dosyasında çağrılması gerekir.
CSS.paintWorklet.addModule("path/to/worklet/file.js");
Herhangi bir Worklet ayrıca harici bir URL'den (örneğin bir İçerik Dağıtım Ağı'ndan) eklenebilir, bu da onları modüler ve yeniden kullanılabilir hale getirir.
CSS.paintWorklet.addModule("https://url/to/worklet/file.js");
Worklet çağrıldıktan sonra, paint
fonksiyonu kullanılarak CSS içinde kullanılabilir. Bu işlev, Worklet'in kayıtlı adını ilk giriş argümanı olarak kabul eder ve onu takip eden her giriş argümanı, Worklet'e (Worklet'in inputArguments
içinde tanımlanır) iletilebilen özel bir argümandır. Bu noktadan itibaren tarayıcı, Worklet'in ne zaman çağrılacağını ve hangi kullanıcı eylemlerinin ve CSS özel özellikleri değerinin yanıt verileceğini belirler.
.exampleElement { /* paintWorkletExample - name of the worklet blue - argument passed to a Worklet */ background-image: paint(paintWorketExample, blue); }
Örnek vermek
Aşağıdaki örnek, Paint API'sini ve genel Worklet yeniden kullanılabilirliğini ve modülerliğini gösterir. Doğrudan Google Chrome Labs deposundan ripple Worklet'i kullanıyor ve farklı stillere sahip farklı bir öğe üzerinde çalışıyor. Örnek depoda eksiksiz kaynak kodu mevcuttur.
Özellik algılama
if ("paintWorklet" in CSS) { /* ... */ } @supports(background:paint(paintWorketExample)){ /* ... */ }
W3C Spesifikasyon Durumu
- Aday tavsiyesi: uygulamaya hazır kararlı çalışma taslağı
Tarayıcı Desteği
Google Chrome | Microsoft Kenarı | Opera Tarayıcı | Firefox | Safari |
---|---|---|---|---|
Desteklenen | Desteklenen | Desteklenen | Desteklenmiyor | Desteklenmiyor |
Veri kaynağı: Houdini Henüz Hazır mı?
Animasyon API'si
Animation API, web animasyonlarını çeşitli olayları (kaydırma, fareyle üzerine gelme, tıklama vb.) dinleme seçenekleriyle genişletir ve bir Animation Worklet kullanarak animasyonları kendi özel iş parçacığında çalıştırarak performansı artırır. Kullanıcı eyleminin, performans gösteren, engellenmeyen bir şekilde çalışan animasyon akışını kontrol etmesine olanak tanır.
Herhangi bir Worklet gibi, önce Animation Worklet'in kaydedilmesi gerekir.
registerAnimator("animationWorkletExample", class { constructor(options) { /* ... */ } animate(currentTime, effect) { /* ... */ } });
Bu sınıf iki işlevden oluşur:
-
constructor
: yeni bir örnek oluşturulduğunda çağrılır. Genel kurulum için kullanılır. -
animate
: animasyon mantığını içeren ana işlev. Aşağıdaki girdi bağımsız değişkenlerini sağlar:-
currentTime
: tanımlanan zaman çizelgesinden geçerli zaman değeri -
effect
: bu animasyonun kullandığı bir dizi efekt
-
Animation Worklet kaydedildikten sonra ana JavaScript dosyasına dahil edilmesi, animasyonun (eleman, anahtar kareler, seçenekler) tanımlanması ve seçilen zaman çizelgesi ile animasyonun somutlaştırılması gerekir. Zaman çizelgesi kavramları ve web animasyonunun temelleri bir sonraki bölümde açıklanacaktır.
/* 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 */
Zaman Çizelgesi Eşlemesi
Web animasyonu, zaman çizelgelerine ve geçerli zamanın bir efektin yerel saatinin zaman çizelgesine eşlenmesine dayanır. Örneğin, bir sayfa yüklendikten (gecikme) 1 saniye sonra çalışan ve 4 saniye süreli 3 ana kareli (başlangıç, orta, son) yinelenen bir doğrusal animasyona bakalım.
Örnekteki efekt zaman çizelgesi şöyle görünecektir (4 saniyelik süre ile gecikme olmaksızın):
Etki zaman çizelgesi (4s süre) | animasyon karesi |
---|---|
0ms | İlk animasyon karesi - animasyon başlar |
2000ms | Orta animasyon karesi - devam eden animasyon |
4000 ms | Son animasyon karesi - animasyon biter veya ilk animasyon karesine sıfırlanır |
effect.localTime öğesini daha iyi anlamak için, değerini effect.localTime
olarak ayarlayarak (1000ms gecikmeyi dikkate alarak), ortaya çıkan animasyon, efekt zaman çizelgesinde bir orta ana kareye kilitlenecektir (orta ana kare için 1000ms gecikme + 2000ms). Animasyon 4000ms aralıklarla (animasyon süresi) tekrarlandığından, değeri 7000ms ve 11000ms olarak ayarlayarak aynı etki gerçekleşecektir.
animate(currentTime, effect) { effect.localTime = 3000; // 1000ms delay + 2000ms middle keyframe }
Sabit bir effect.localTime
değerine sahipken animasyon olmaz çünkü animasyon belirli bir ana karede kilitlenir. Bir öğeyi düzgün şekilde canlandırmak için, effect.localTime
dinamik olması gerekir. Değerin, currentTime
girdi bağımsız değişkenine veya başka bir değişkene bağlı bir işlev olması gerekir.
Aşağıdaki kod, yerel saati etkilemek için bir zaman çizelgesinin 1:1 (doğrusal işlev) eşlemesinin işlevsel bir temsilini gösterir.
animate(currentTime, effect) { effect.localTime = currentTime; // y = x linear function }
Zaman Çizelgesi ( document.timeline çizelgesi ) | Eşlenen efekt yerel saat | animasyon karesi |
---|---|---|
startTime + 0ms (geçen süre) | startTime + 0ms | Öncelikle |
startTime + 1000ms (geçen süre) | startTime + 1000ms (gecikme) + 0ms | Öncelikle |
startTime + 3000ms (geçen süre) | startTime + 1000ms (gecikme) + 2000ms | Orta |
startTime + 5000ms (geçen süre) | startTime + 1000ms (gecikme) + 4000ms | Son ilk |
startTime + 7000ms (geçen süre) | startTime + 1000ms (gecikme) + 6000ms | Orta |
startTime + 9000ms (geçen süre) | startTime + 1000ms (gecikme) + 8000ms | Son ilk |
Zaman çizelgesi, efektin yerel saatiyle 1:1 eşlemeyle sınırlı değildir. Animasyon API'si, geliştiricilerin, karmaşık zaman çizelgeleri oluşturmak için standart JavaScript işlevlerini kullanarak animate
işlevinde zaman çizelgesi eşlemesini değiştirmesine olanak tanır. Animasyonun her yinelemede aynı şekilde davranması da gerekmez (animasyon tekrarlanıyorsa).
Animasyon, yüklendiği andan itibaren yalnızca milisaniyeleri saymaya başlayan belgenin zaman çizelgesine bağlı olmak zorunda değildir. Kaydırma olayları gibi kullanıcı eylemleri, bir ScrollTimeline
nesnesi kullanılarak animasyon için bir zaman çizelgesi olarak kullanılabilir. Örneğin, bir animasyon, bir kullanıcı 200 piksele kaydırdığında başlayabilir ve bir kullanıcı ekranda 800 piksele kaydırdığında sona erebilir.
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 */ }); ...
Animasyon, kullanıcının kaydırma hızına otomatik olarak uyum sağlayacak ve sorunsuz ve duyarlı kalacaktır. Animation Worklet'ler ana iş parçacığından çalıştığından ve bir tarayıcının işleme motoruna bağlı olduğundan, kullanıcı kaydırmasına bağlı olan animasyon sorunsuz çalışabilir ve çok performanslı olabilir.
Örnek vermek
Aşağıdaki örnek, doğrusal olmayan bir zaman çizelgesi uygulamasının nasıl olduğunu gösterir. Değiştirilmiş Gauss işlevini kullanır ve aynı zaman çizelgesiyle öteleme ve döndürme animasyonu uygular. Örnek depoda eksiksiz kaynak kodu mevcuttur.
Özellik Algılama
if (CSS.animationWorklet) { /* ... */ }
W3C Spesifikasyon Durumu
- İlk Kamu Çalışma Taslağı: topluluk incelemesine hazır, spesifikasyon değişikliğine açık
Tarayıcı Desteği
Google Chrome | Microsoft Kenarı | Opera Tarayıcı | Firefox | Safari |
---|---|---|---|---|
Kısmi destek (*) | Kısmi destek (*) | Kısmi destek (*) | Desteklenmiyor | Desteklenmiyor |
* “Deneysel Web Platformu özellikleri” bayrağı etkinleştirilerek desteklenir.
Veri kaynağı: Houdini Henüz Hazır mı?
Düzen API'si
Düzen API'si, geliştiricilerin, display
CSS özelliğinde kullanılabilecek yeni düzen modları tanımlayarak tarayıcının düzen oluşturma sürecini genişletmesine olanak tanır. Layout API, yeni kavramlar sunar, çok karmaşıktır ve özel düzen algoritmaları geliştirmek için birçok seçenek sunar.
Diğer Worklet'lere benzer şekilde, önce Worklet düzeninin kaydedilmesi ve tanımlanması gerekir.
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) { /* ... */ } });
Worklet kaydı aşağıdaki yöntemleri içerir:
-
inputProperties
:
Bir Ana Düzen öğesine, yani bu düzeni çağıran öğeye ait olan, Worklet'in takip edeceği bir CSS özel özellikleri dizisi. Bu dizi, bir Layout Worklet'in bağımlılıklarını temsil eder. -
childrenInputProperties
:
Bir Ana Düzen öğesinin alt öğelerine, yani bu düzeni ayarlayan öğelerin alt öğelerine ait olan, Çalışma Uygulamasının izleyeceği bir CSS özel özellikleri dizisi. -
layoutOptions
: aşağıdaki düzen özelliklerini tanımlar:-
childDisplay
: önceden tanımlanmış birblock
veyanormal
değerine sahip olabilir. Kutuların blok olarak mı yoksa satır içi olarak mı görüntüleneceğini belirler. -
sizing
: önceden tanımlanmışblock-like
veyamanual
bir değere sahip olabilir. Tarayıcıya sırasıyla boyutu önceden hesaplamasını veya önceden hesaplamamasını söyler (bir boyut açıkça ayarlanmadıkça).
-
-
intrinsicSizes
: bir kutunun veya içeriğinin bir düzen bağlamına nasıl uyduğunu tanımlar.-
children
: Bir Ana Düzen öğesinin alt öğeleri, yani bu düzeni çağıran öğenin çocukları. -
edges
: Düzen Bir kutunun kenarları -
styleMap
: bir kutunun OM stilleri yazıldı
-
-
layout
: Bir düzeni gerçekleştiren ana işlev.-
children
: Bir Ana Düzen öğesinin alt öğeleri, yani bu düzeni çağıran öğenin çocukları. -
edges
: Düzen Bir kutunun kenarları -
constraints
: bir Ebeveyn Düzeninin kısıtlamaları -
styleMap
: bir kutunun OM stilleri yazıldı -
breakToken
: sayfalandırma veya yazdırma durumunda bir düzeni sürdürmek için kullanılan kesme belirteci.
-
Paint API durumunda olduğu gibi, tarayıcı oluşturma motoru, paint Worklet'in ne zaman çağrılacağını belirler. Yalnızca bir HTML veya ana JavaScript dosyasına eklenmesi gerekir.
CSS.layoutWorklet.addModule('path/to/worklet/file.js');
Ve son olarak, bir CSS dosyasında referans verilmesi gerekiyor
.exampleElement { display: layout(exampleLayout); }
Layout API, Layout'u Nasıl Gerçekleştirir?
Önceki örnekte, exampleLayout
, Layout API kullanılarak tanımlanmıştır.
.exampleElement { display: layout(exampleLayout); }
Bu öğe, dolgular, kenarlıklar ve kaydırma çubuklarından oluşan Düzen Kenarları ile çevrelenen Ana Düzen olarak adlandırılır. Ana Düzen, Geçerli Düzenler adı verilen alt öğelerden oluşur. Mevcut Düzenler, Düzen API'sı kullanılarak düzeni özelleştirilebilen gerçek hedef öğelerdir. Örneğin, display: flex;
bir öğede, alt öğeleri esnek düzeni oluşturmak için yeniden konumlandırılıyor. Bu, Düzen API'si ile yapılanlara benzer.
Her Geçerli Düzen , LayoutChild için bir düzen algoritması olan Alt Düzen'den oluşur (eleman, ::before
ve ::after
sözde öğeler) ve LayoutChild , yalnızca stil verilerini içeren (düzen verisi yok) CSS tarafından oluşturulan bir kutudur. LayoutChild öğeleri, stil adımında tarayıcı oluşturma motoru tarafından otomatik olarak oluşturulur. Layout Child, gerçekten mizanpaj oluşturma eylemlerini gerçekleştiren bir Fragment oluşturabilir.
Örnek vermek
Paint API örneğine benzer şekilde, bu örnek bir duvar düzeni Worklet'i doğrudan Google Chrome Labs deposundan içe aktarmaktadır, ancak bu örnekte metin yerine resim içeriği ile kullanılmıştır. Örnek depoda eksiksiz kaynak kodu mevcuttur.
Özellik Algılama
if (CSS.layoutWorklet) { /* ... */ }
W3C Spesifikasyon Durumu
- İlk Kamu Çalışma Taslağı: topluluk incelemesine hazır, spesifikasyon değişikliğine açık
Tarayıcı Desteği
Google Chrome | Microsoft Kenarı | Opera Tarayıcı | Firefox | Safari |
---|---|---|---|---|
Kısmi destek (*) | Kısmi destek (*) | Kısmi destek (*) | Desteklenmiyor | Desteklenmiyor |
* “Deneysel Web Platformu özellikleri” bayrağı etkinleştirilerek desteklenir.
Veri kaynağı: Houdini Henüz Hazır mı?
Houdini ve Aşamalı Geliştirme
CSS Houdini henüz optimal tarayıcı desteğine sahip olmasa da, günümüzde aşamalı geliştirme göz önünde bulundurularak kullanılabilir. Aşamalı geliştirme hakkında bilginiz yoksa, bunu gerçekten iyi açıklayan bu kullanışlı makaleye göz atmaya değer. Houdini'yi bugün projenize uygulamaya karar verirseniz, aklınızda bulundurmanız gereken birkaç şey vardır:
- Hataları önlemek için özellik algılamayı kullanın.
Her Houdini API ve Worklet, tarayıcıda mevcut olup olmadığını kontrol etmenin basit bir yolunu sunar. Houdini geliştirmelerini yalnızca onu destekleyen tarayıcılara uygulamak ve hatalardan kaçınmak için özellik algılamayı kullanın. - Yalnızca sunum ve görsel iyileştirme için kullanın.
Henüz Houdini'yi desteklemeyen bir tarayıcıda bir web sitesine göz atan kullanıcılar, web sitesinin içeriğine ve temel işlevlerine erişebilmelidir. Kullanıcı deneyimi ve içerik sunumu, Houdini özelliklerine bağlı olmamalı ve güvenilir bir geri dönüşe sahip olmalıdır. - Standart bir CSS yedeğini kullanın.
Örneğin, normal CSS Özel Özellikleri, Özel Özellikler ve Değerler API'sı kullanılarak tanımlanan stiller için yedek olarak kullanılabilir.
Önce performanslı ve güvenilir bir web sitesi kullanıcı deneyimi geliştirmeye odaklanın ve ardından Houdini özelliklerini aşamalı bir geliştirme olarak dekoratif amaçlarla kullanın.
Çözüm
Houdini API'leri, sonunda geliştiricilerin stil işleme ve dekorasyon için kullanılan JavaScript kodunu tarayıcının işleme hattına daha yakın tutmasını sağlayarak daha iyi performans ve kararlılıkla sonuçlanacak. Geliştiricilerin tarayıcı oluşturma sürecine bağlanmasına izin vererek, kolayca paylaşılabilen, uygulanabilen ve potansiyel olarak CSS spesifikasyonuna eklenebilen çeşitli CSS çoklu dolguları geliştirebilecekler. Houdini ayrıca stil, düzen ve animasyonlar üzerinde çalışırken geliştiricilerin ve tasarımcıların CSS sınırlamaları tarafından daha az kısıtlanmasını sağlayarak yeni keyifli web deneyimleriyle sonuçlanacak.
CSS Houdini özellikleri bugün projelere eklenebilir, ancak kesinlikle aşamalı geliştirme göz önünde bulundurularak. Bu, Houdini özelliklerini desteklemeyen tarayıcıların web sitesini hatasız hale getirmesini ve optimum kullanıcı deneyimi sunmasını sağlayacaktır.
Houdini ilgi ve daha iyi tarayıcı desteği kazandıkça, geliştirici topluluğunun neler yapacağını izlemek heyecan verici olacak. İşte topluluktan bazı harika Houdini API deneyleri örnekleri:
- CSS Houdini Deneyleri
- CSS Houdini'ye Etkileşimli Giriş
- Google Chrome Laboratuvarlarından Houdini Örnekleri
Referanslar
- W3C Houdini Spesifikasyon Taslakları
- Houdini Eyaleti (Chrome Geliştirme Zirvesi 2018)
- Houdini'nin Animasyon Çalışması - Google Developers
- CSS Houdini'ye Etkileşimli Giriş