تاريخ النشر: 22 سبتمبر 2025
عند بدء انتقال للعرض، يلتقط المتصفّح تلقائيًا لقطات قبل وبعد للعناصر التي تم وضع علامة view-transition-name عليها. يتم عرض هذه اللقطات في شجرة من العناصر الزائفة. يكون التسلسل الهرمي الذي يتم إنشاؤه "مسطّحًا" بشكل تلقائي. وهذا يعني أنّ التسلسل الهرمي الأصلي في نموذج DOM يُفقد، وأنّ جميع مجموعات انتقال العرض التي تم تسجيلها هي عناصر شقيقة ضمن عنصر زائف واحد من النوع ::view-transition.
هذا النهج كافٍ للعديد من حالات الاستخدام، ولكن هناك بعض حالات الاستخدام التي لا يمكن تحقيقها من خلاله. في ما يلي أمثلة على التأثيرات التي يمكن أن يكون لها تأثير مرئي غير متوقّع في شجرة مسطّحة:
- الاقتصاص (
overflowوclip-pathوborder-radius): يؤثر الاقتصاص في العناصر الثانوية للعنصر، ما يعني أنّ العناصر التابعة لمجموعة انتقال العرض لا يمكنها اقتصاص بعضها البعض. -
opacityوmask-imageوfilter: تم تصميم هذه التأثيرات لتعمل على صورة شجرة تم تنقيطها بالكامل، ما يؤثر في العناصر الفرعية بدلاً من التأثير في كل عنصر على حدة. - عمليات التحويل الثلاثية الأبعاد (
transform-styleوtransformوperspective): لعرض المجموعة الكاملة من الصور المتحركة لعمليات التحويل الثلاثية الأبعاد، يجب الحفاظ على بعض التسلسل الهرمي.
يوضّح المثال التالي شجرة زائفة مسطّحة، مع عناصر تم اقتصاصها من خلال عنصر رئيسي في شجرة نموذج العناصر في المستند. تفقد هذه العناصر اقتصاصها أثناء انتقال العرض، ما يؤدي إلى تأثير مرئي معطّل.
مجموعات انتقالات العرض المضمّنة هي إضافة لانتقالات العرض تتيح لك تضمين عناصر ::view-transition-group الزائفة داخل بعضها. عند تداخل مجموعات انتقال العرض، من الممكن استعادة تأثيرات مثل الاقتصاص أثناء الانتقال.
Browser Support
من شجرة زائفة مسطّحة إلى شجرة زائفة متداخلة
في العرض التوضيحي التالي، يمكنك النقر على الصورة الرمزية لشخص ما للاطّلاع على مزيد من المعلومات عنه. تتم معالجة الصور المتحركة من خلال انتقال عرض المستند نفسه الذي يحوّل الزر الذي تم النقر عليه إلى مربّع الحوار، وينقل الصورة الرمزية والاسم على الشاشة، ويحرّك الفقرات من مربّع الحوار للأعلى أو للأسفل.
عرض توضيحي مباشر
تسجيل تجريبي
تسجيل تجريبي (بسرعة بطيئة)
إذا نظرت عن كثب إلى العرض التوضيحي، ستلاحظ أنّ هناك مشكلة في عملية الانتقال: على الرغم من أنّ الفقرات التي تتضمّن الوصف هي عناصر فرعية للعنصر <dialog> في نموذج DOM، لا يتم اقتصاص النص من خلال مربّع <dialog> أثناء عملية الانتقال:
<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 على <dialog> إلى أي نتيجة.
تكمن المشكلة في طريقة إنشاء انتقالات العرض وعرض شجرة العناصر الزائفة:
- في الشجرة الزائفة، تكون جميع اللقطات تلقائيًا تابعة لبعضها البعض.
- يتم عرض الشجرة الزائفة في عنصر زائف
::view-transitionيتم عرضه في أعلى المستند بأكمله.
بالنسبة إلى هذا العرض التوضيحي تحديدًا، تبدو شجرة نموذج العناصر في المستند على النحو التالي:
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) هي عناصر تابعة للعنصر الزائف ::view-transition-group(card)، يتم رسمها في أعلى البطاقة.
لاقتصاص ::view-transition-group(.text) من ::view-transition-group(card)، يجب أن تكون العناصر الزائفة ::view-transition-group(.text) تابعة لـ ::view-transition-group(card). لذلك، يمكنك استخدام view-transition-group التي تتيح لك تعيين "مجموعة رئيسية" لعنصر زائف ::view-transition-group() تم إنشاؤه.
لتغيير المجموعة الرئيسية، يتوفّر لك خياران:
- في العنصر الرئيسي، اضبط السمة
view-transition-groupعلىcontain، لكي يحتوي على جميع العناصر الفرعية التي تتضمّن السمةview-transition-name. - في جميع العناصر الفرعية، اضبط السمة
view-transition-groupعلى قيمة السمةview-transition-nameللعنصر الرئيسي. يمكنك أيضًا استخدامnearestلاستهداف أقرب مجموعة أصلية.
لذلك، في هذا العرض التوضيحي، لاستخدام مجموعات انتقالات العرض المُدمَجة، يصبح الرمز البرمجي على النحو التالي:
button.clicked,
dialog {
view-transition-group: contain;
}
أو
button.clicked,
dialog *,
view-transition-group: nearest;
}
بعد الانتهاء من إعداد هذا الرمز البرمجي، يتم الآن دمج عناصر ::view-transition-group(.text) الزائفة داخل عنصر ::view-transition-group(card) الزائف. ويتم ذلك في فئة زائفة إضافية من النوع ::view-transition-group-children(…)، ما يحافظ على تجميع كل الفئات الزائفة المتداخلة معًا:
html
├─ ::view-transition
│ ├─ ::view-transition-group(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-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)
├─ head
└─ body
└─ …
أخيرًا، لكي يقتطع العنصر الزائف ::view-transition-group(card) الفقرات، طبِّق overflow: clip على العنصر الزائف ::view-transition-group-children(card):
::view-transition-group-children(card) {
overflow: clip;
}
والنتيجة هي:
عرض توضيحي مباشر
تسجيل تجريبي
تسجيل تجريبي (بسرعة بطيئة)
لا يتوفّر العنصر الزائف ::view-transition-group-children إلا عند استخدام المجموعات المُدمجة. يتم تحديد حجمه وفقًا لمربّع الحدود للعنصر الأصلي ويتم منحه حدودًا شفافة بالشكل وسُمك الحدود نفسهما للعنصر الذي أنشأ العنصر الزائف، وهو card في المثال السابق.
القطع والمزيد
تُستخدَم مجموعات انتقالات العرض المضمّنة في أماكن أخرى غير تأثيرات الاقتصاص. مثال آخر هو التأثيرات الثلاثية الأبعاد. في العرض التوضيحي التالي، يتوفّر خيار لتدوير البطاقة بشكل ثلاثي الأبعاد أثناء عملية النقل.
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;
}
}
بدون مجموعات انتقالات العرض المُدمَجة، لا يتم تدوير الصورة الرمزية والاسم مع البطاقة.
عرض توضيحي مباشر
تسجيل تجريبي
تسجيل تجريبي (بسرعة بطيئة)
من خلال دمج العناصر الزائفة للأفاتار والاسم داخل البطاقة، يمكن استعادة التأثير الثلاثي الأبعاد. ولكن هذا ليس الإجراء الوحيد الذي عليك اتّخاذه، فبالإضافة إلى تدوير العنصرَين الزائفَين ::view-transition-old(card) و::view-transition-new(card)، عليك أيضًا تدوير العنصر الزائف ::view-transition-group-children(card).
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;
}
}
عرض توضيحي مباشر
تسجيل تجريبي
تسجيل تجريبي (بسرعة بطيئة)
المزيد من العروض التوضيحية
في المثال التالي، يتم استخدام مجموعات انتقالات العرض المدمجة للتأكّد من اقتصاص البطاقات من خلال شريط التمرير الرئيسي. يمكنك تفعيل استخدام مجموعات الانتقال في العرض المضمّنة أو إيقافها باستخدام عناصر التحكّم المضمّنة.
عرض توضيحي مباشر
تسجيل تجريبي
الأمر المثير للاهتمام في هذا العرض التوضيحي هو أنّ جميع العناصر الزائفة ::view-transition-group(.card) يتم دمجها داخل العنصر الزائف ::view-transition-group(cards) الأساسي واقتصاصها من خلاله. يتم استبعاد #targeted-card لأنّه يجب عدم اقتصاص تأثيرات الدخول والخروج المتحركة من خلال ::view-transition-group(cards).
/* 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;
}
ملخّص
تتيح لك انتقالات العرض المدمجة الحفاظ على بعض بنية شجرة نموذج العناصر في المستند (DOM) عند إنشاء العناصر الزائفة. يؤدي ذلك إلى إتاحة مجموعة متنوعة من التأثيرات التي لم تكن ممكنة في السابق باستخدام انتقالات العرض، وقد وصفنا بعضها هنا.
يؤدي التداخل إلى تغيير نموذج كيفية إنشاء انتقالات العرض، ويهدف إلى استخدامه لإنشاء تأثيرات متقدّمة. كما ذكرنا، يمكن أيضًا أن تحقّق انتقالات العرض على مستوى العنصر مجموعة فرعية من التأثيرات باستخدام نموذج أبسط. ننصحك بتجربة كلتا الميزتَين لتحديد الميزة الأنسب لاحتياجاتك.