Yayınlanma tarihi: 22 Eylül 2025
Görünüm geçişi başlattığınızda tarayıcı, view-transition-name
ile etiketlenmiş öğelerin öncesi ve sonrası anlık görüntülerini otomatik olarak alır. Bu anlık görüntüler, sözde öğelerden oluşan bir ağaçta oluşturulur. Oluşturulan ağaç varsayılan olarak "düz" olur. Bu durumda, DOM'daki orijinal hiyerarşi kaybolur ve yakalanan tüm görünüm geçişi grupları tek bir ::view-transition
sözde öğesi altında kardeş öğeler olur.
Bu düz ağaç yaklaşımı birçok kullanım alanı için yeterli olsa da bazı stil kullanım alanlarında bu yaklaşımla istenen sonuç elde edilemez. Aşağıda, düz ağaçta beklenmedik görsel etkilere neden olabilecek efektlere örnekler verilmiştir:
- Kırpma (
overflow
,clip-path
,border-radius
): Kırpma, öğenin alt öğelerini etkiler. Bu nedenle, görünüm geçişi grubu kardeşleri birbirini kırpamaz. opacity
,mask-image
vefilter
: Benzer şekilde, bu efektler de her öğeyi ayrı ayrı etkilemek yerine, ağacın tamamen rasterleştirilmiş bir görüntüsünde çalışacak şekilde tasarlanmıştır ve alt öğeleri etkiler.- 3D dönüştürmeler (
transform-style
,transform
,perspective
): 3D dönüştürme animasyonlarının tamamını görüntülemek için belirli bir hiyerarşinin korunması gerekir.
Aşağıdaki örnekte, DOM ağacındaki bir üst öğe tarafından kırpılan öğeleri içeren düz bir sözde ağaç gösterilmektedir. Bu öğeler, görünüm geçişi sırasında kırpma özelliğini kaybederek bozuk bir görsel efekt oluşturur.
İç içe görünüm geçişi grupları, görünüm geçişlerinin bir uzantısıdır ve ::view-transition-group
sözde öğelerini iç içe yerleştirmenize olanak tanır. Görünüm geçişi grupları iç içe yerleştirildiğinde, geçiş sırasında kırpma gibi efektleri geri yüklemek mümkündür.
Browser Support
Düz bir sahte ağaçtan iç içe yerleştirilmiş bir sahte ağaca
Aşağıdaki demoda, bir kişinin avatarını tıklayarak o kişi hakkında daha fazla bilgi edinebilirsiniz. Animasyonlar, tıklanan düğmeyi iletişim kutusuna dönüştüren, avatarı ve adı ekranda hareket ettiren ve iletişim kutusundaki paragrafları yukarı veya aşağı kaydıran aynı belge görünümü geçişiyle işlenir.
Canlı Demo
Demo Kaydı
Demo Kaydı (Yavaşlatılmış)
Demoya yakından bakarsanız geçişle ilgili bir sorun olduğunu görürsünüz: Açıklama içeren paragraflar DOM'daki <dialog>
öğesinin alt öğeleri olsa da metin, geçiş sırasında <dialog>
öğesinin kutusu tarafından kırpılmaz:
<dialog id="info_bramus" closedby="any">
<h2><img alt="…" class="avatar" height="96" width="96" src="avatar_bramus.jpg"> <span>Bramus</span></h2>
<p>Bramus is …</p>
<p>…</p>
</dialog>
overflow: clip
simgesini <dialog>
üzerinde uygulamak da herhangi bir işlem yapmaz.
Sorun, görünüm geçişlerinin sözde ağaçlarını oluşturma ve oluşturma şeklinden kaynaklanmaktadır:
- Sözde ağaçta, varsayılan olarak tüm anlık görüntüler birbirinin kardeşidir.
- Sözde ağaç, dokümanın tamamının üzerinde oluşturulan bir
::view-transition
sözde öğesinde oluşturulur.
Bu demo için DOM ağacı aşağıdaki gibi görünür:
html
├─ ::view-transition
│ ├─ ::view-transition-group(card)
│ │ └─ ::view-transition-image-pair(card)
│ │ ├─ ::view-transition-old(card)
│ │ └─ ::view-transition-new(card)
│ ├─ ::view-transition-group(name)
│ │ └─ ::view-transition-image-pair(name)
│ │ ├─ ::view-transition-old(name)
│ │ └─ ::view-transition-new(name)
│ ├─ ::view-transition-group(avatar)
│ │ └─ ::view-transition-image-pair(avatar)
│ │ ├─ ::view-transition-old(avatar)
│ │ └─ ::view-transition-new(avatar)
│ ├─ ::view-transition-group(paragraph1.text)
│ │ └─ ::view-transition-image-pair(paragraph1.text)
│ │ └─ ::view-transition-new(paragraph1.text)
│ └─ ::view-transition-group(paragraph2.text)
│ └─ ::view-transition-image-pair(paragraph2.text)
│ └─ ::view-transition-new(paragraph2.text)
├─ head
└─ body
└─ …
::view-transition-group(.text)
sözde sınıfları, ::view-transition-group(card)
sözde sınıflarının kardeşleri olduğu için kartın üzerine çizilir.
::view-transition-group(card)
klibi ::view-transition-group(.text)
için ::view-transition-group(.text)
sözde öğeleri, ::view-transition-group(card)
öğesinin alt öğeleri olmalıdır. Bunun için, oluşturulan bir ::view-transition-group()
sözde öğesine "üst grup" atamanıza olanak tanıyan view-transition-group
özelliğini kullanın.
Üst grubu değiştirmek için iki seçeneğiniz vardır:
view-transition-name
içeren tüm alt öğeleri içermesi için üst öğedeview-transition-group
özelliğinicontain
olarak ayarlayın.- Tüm alt öğelerde
view-transition-group
değerini üst öğeninview-transition-name
değerine ayarlayın. En yakın üst grubu hedeflemek içinnearest
simgesini de kullanabilirsiniz.
Bu nedenle, bu demoda iç içe görünüm geçişi gruplarını kullanmak için kod şu şekilde olur:
button.clicked,
dialog {
view-transition-group: contain;
}
Alternatif seçenek:
button.clicked,
dialog *,
view-transition-group: nearest;
}
Bu kod yerleştirildiğinde, ::view-transition-group(.text)
sözde sınıfları artık ::view-transition-group(card)
sözde sınıfının içine yerleştirilir. Bu işlem, tüm iç içe yerleştirilmiş sözde sınıfları bir arada tutan ek bir ::view-transition-group-children(…)
sözde sınıfında yapılır:
html
├─ ::view-transition
│ ├─ ::view-transition-group(card)
│ │ ├─ ::view-transition-image-pair(card)
│ │ │ ├─ ::view-transition-old(card)
│ │ │ └─ ::view-transition-new(card)
│ │ └─::view-transition-group-children(card)
│ │ ├─ ::view-transition-group(paragraph1.text)
│ │ │ └─ ::view-transition-image-pair(paragraph1.text)
│ │ │ └─ ::view-transition-new(paragraph1.text)
│ │ └─ ::view-transition-group(paragraph2.text)
│ │ └─ ::view-transition-image-pair(paragraph2.text)
│ │ └─ ::view-transition-new(paragraph2.text)
│ ├─ ::view-transition-group(name)
│ │ └─ ::view-transition-image-pair(name)
│ │ ├─ ::view-transition-old(name)
│ │ └─ ::view-transition-new(name)
│ └─ ::view-transition-group(avatar)
│ └─ ::view-transition-image-pair(avatar)
│ ├─ ::view-transition-old(avatar)
│ └─ ::view-transition-new(avatar)
├─ head
└─ body
└─ …
Son olarak, ::view-transition-group(card)
sözde öğesinin paragrafları kırpması için overflow: clip
sözde öğesini ::view-transition-group-children(card)
sözde öğesine uygulayın:
::view-transition-group-children(card) {
overflow: clip;
}
Sonuç şöyledir:
Canlı Demo
Demo Kaydı
Demo Kaydı (Yavaşlatılmış)
::view-transition-group-children
sahtesi yalnızca iç içe yerleştirilmiş gruplar kullanıldığında bulunur. Orijinal öğenin border-box'ına göre boyutlandırılır ve sözde öğeyi oluşturan öğeyle (önceki örnekteki card
) aynı şekle ve kenarlık kalınlığına sahip şeffaf bir kenarlık verilir.
Kırpma ve daha fazlası
İç içe yerleştirilmiş görünüm geçişi grupları, kırpma efektleri dışında yerlerde kullanılır. 3D efektler de başka bir örnektir. Aşağıdaki demoda, geçiş sırasında kartı 3D olarak döndürme seçeneği vardır.
html:active-view-transition-type(open) {
&::view-transition-old(card) {
animation-name: rotate-out;
}
&::view-transition-new(card) {
animation-name: rotate-in;
}
}
html:active-view-transition-type(close) {
&::view-transition-old(card) {
animation-name: rotate-in;
}
&::view-transition-new(card) {
animation-name: rotate-out;
}
}
İç içe görünüm geçişi grupları olmadan, avatar ve ad kartla birlikte dönmez.
Canlı Demo
Demo Kaydı
Demo Kaydı (Yavaşlatılmış)
Avatar ve ad takma adları kartın içine yerleştirerek 3D efekt geri yüklenebilir. Ancak yapmanız gereken tek şey bu değil. ::view-transition-old(card)
ve ::view-transition-new(card)
sahtelerini döndürmenin yanı sıra ::view-transition-group-children(card)
sahtesini de döndürmeniz gerekir.
html:active-view-transition-type(open) {
&::view-transition-group-children(card) {
animation: rotate-in var(--duration) ease;
backface-visibility: hidden;
}
}
html:active-view-transition-type(close) {
&::view-transition-group-children(card) {
animation: rotate-out var(--duration) ease;
backface-visibility: hidden;
}
}
Canlı Demo
Demo Kaydı
Demo Kaydı (Yavaşlatılmış)
Daha fazla demo
Aşağıdaki örnekte, kartların üst öğe kaydırıcı tarafından kırpıldığından emin olmak için iç içe görünüm geçişi grupları kullanılmaktadır. İç içe yerleştirilmiş görünüm geçişi gruplarının kullanımını, sağlanan kontrolleri kullanarak etkinleştirebilir veya devre dışı bırakabilirsiniz.
Canlı Demo
Demo Kaydı
Bu demoyla ilgili ilginç nokta, tüm ::view-transition-group(.card)
sözde öğelerinin, üst öğe ::view-transition-group(cards)
sözde öğesinin içine yerleştirilip bu öğe tarafından kırpılmasıdır. #targeted-card
animasyonu, giriş/çıkış animasyonu ::view-transition-group(cards)
tarafından kırpılmaması gerektiğinden hariç tutulur.
/* The .cards wrapper contains all children */
.cards {
view-transition-name: cards;
view-transition-group: contain;
}
/* Contents that bleed out get clipped */
&::view-transition-group-children(cards) {
overflow: clip;
}
/* Each card is given a v-t-name and v-t-class */
.card {
view-transition-name: match-element;
view-transition-class: card;
}
/* The targeted card is given a unique name (to style the pseudo differently)
and shouldn't be contained by the ::view-transition-group-children(cards) pseudo */
#targeted-card {
view-transition-name: targeted-card;
view-transition-group: none;
}
Özet
İç içe görünüm geçişleri, sözde öğeleri oluştururken DOM ağacının topolojisinin bir kısmını korumanıza olanak tanır. Bu, görüntüleme geçişleriyle daha önce mümkün olmayan çeşitli efektlerin kullanılmasını sağlar. Bu efektlerden bazılarını burada açıkladık.
İç içe yerleştirme, görünüm geçişlerinin oluşturulma modelini değiştirir ve gelişmiş efektler oluşturmak için kullanılır. Belirtildiği gibi, öğe kapsamlı görünüm geçişleri de daha basit bir modelle efektlerin bir alt kümesini gerçekleştirebilir. İhtiyaçlarınıza en uygun olanı belirlemek için her iki özelliği de denemenizi öneririz.