- Moderatör
- #1
- Kayıtlı
- 1 Yıl 9 Ay 26 Gün
- Katılım
- 10 Ocak 2025
- Konular
- 163
- Mesajlar
- 257
- Tepkime puanı
- 36
- Online süresi
- 11h 19m
- Puan
- 53
- Konum
- Türkiye
- Web sitesi
- www.zyncra.shop
View Transition API ile Sayfa Geçişlerini Canlandırmak: Tek Satır CSS ile Sayfalar Arası Geçiş ve startViewTransition ile Kart Ekleme
1. Kart Listesinden Detay Sayfasına Görselin Büyüyerek Taşındığı Geçişi, Önce CSS Sonra JavaScript ile Adım Adım Yapıyoruz
Bir karta tıklıyorsunuz, sayfa bir anda beyaz ekrana düşüp yeni içerikle geri geliyor. Kullanıcı neyin nereye gittiğini anlamıyor. Bunu düzeltmek için eskiden SPA'ya geçip animasyon kütüphanesi eklemek gerekiyordu. View Transition API ile düz HTML sayfaları arasında bile, birkaç satır CSS ile görselin listeden detay sayfasındaki büyük kapak alanına kayarak taşınmasını sağlayabiliyorsunuz. Bu konuda önce iki sayfalı bir örnekte bunu kuracağız, sonra aynı mantığı JavaScript ile sayfa içindeki bir değişikliğe (yeni kart eklemek) uygulayacağız.
1. Adım: İki Sayfayı Hazırlamak ve Her Birine @view-transition Kuralını Eklemek
Örnekte
Bu kadarıyla bile sayfalar arasında yumuşak bir çapraz geçiş (cross-fade) görürsünüz. Asıl iş, hangi elemanın hangisine dönüşeceğini tarayıcıya söylemekte.
Sayfaların kökünü ayırt edebilmek için
2. Adım: Geçişi DevTools'ta Yavaşlatmak ve Pseudo-element Ağacını Okumak
Animasyonu gözle yakalayamıyorsanız ayar yapamazsınız. Chrome'da DevTools'u açın, sağ üstteki üç nokta menüsünden More tools > Animations panelini getirin ve hızı %10'a çekin. Duraklatıp sayfalar arasında gezinince Elements panelinde
Bu gruplara CSS ile müdahale edebilirsiniz. Süreyi uzatmak ve kök sayfanın varsayılan geçişini kapatmak için:
Adlandırılmış her grubun içi
Her grubun içinde
3. Adım: Başlığı view-transition-name ile İki Sayfa Arasında Taşımak
Eşleştirmek istediğiniz elemana iki sayfada da aynı
Dikkat edin: aynı sayfada aynı
4. Adım: Görseli Listeden Kapak Alanına Büyüterek Taşımak ve Bozulmaları Düzeltmek
Görsellerin kimlikleri farklı (
Burada
5. Adım: Karşılığı Olmayan Bir Elemanı (Koyu Katman) Keyframes ile İçeri Almak
Detay sayfasındaki koyu katman ve içindeki yazılar
6. Adım: Sayfa İçi Değişiklikte document.startViewTransition ile Yeni Kart Eklemek
JavaScript ile DOM'a eklenen bir kart CSS tarafından yakalanamaz. Bu durumda değişikliği
Önemli satırlar:
7. Adım: React ve Next.js'te Deneysel Bayrakları Açmak
React tarafında
Next.js'te ise
Bunların ikisi de API'si değişebilen özellikler. Üretim projesinde sürümü sabitleyin.
8. Adım: Canlıya Almadan Önce Kontrol Listesi ve Pratik İpuçları
Destek durumu tarayıcıdan tarayıcıya ve sürümden sürüme değişiyor. Sayfalar arası geçiş Chromium tarafında yerleşik; diğer tarayıcılarda sürüm sürüm ilerliyor. Yayına almadan önce güncel uyumluluk tablosuna bakın. Destek olmayan tarayıcıda CSS kuralı yok sayılır ve sayfa normal şekilde açılır; bozulan bir şey olmaz. JavaScript tarafında ise
Hareket azaltma tercihi için şu kural yeterli:
Kendi sitenizde en çok işe yarayacak yer genellikle liste-detay geçişi; önce başlıkla başlayın, sonra görseli ekleyin. Takıldığınız yerleri ya da farklı tarayıcılarda gördüğünüz tuhaflıkları konunun altına yazabilirsiniz, birlikte bakarız.
Sıkça Sorulan Sorular (SSS)
Konu İçeriği — Hızlı Bakış (
cPanel / Web • ⏱ ~7 dk okuma •
Kod: CSS)
01. 1. Adım: İki Sayfayı Hazırlamak ve Her Birine @view-transition Kuralını Eklemek
02. 2. Adım: Geçişi DevTools'ta Yavaşlatmak ve Pseudo-element Ağacını Okumak
03. Adlandırılmış her grubun içi
04. 3. Adım: Başlığı view-transition-name ile İki Sayfa Arasında Taşımak
05. 4. Adım: Görseli Listeden Kapak Alanına Büyüterek Taşımak ve Bozulmaları Düzeltmek
06. 5. Adım: Karşılığı Olmayan Bir Elemanı (Koyu Katman) Keyframes ile İçeri Almak
1. Kart Listesinden Detay Sayfasına Görselin Büyüyerek Taşındığı Geçişi, Önce CSS Sonra JavaScript ile Adım Adım Yapıyoruz
Bir karta tıklıyorsunuz, sayfa bir anda beyaz ekrana düşüp yeni içerikle geri geliyor. Kullanıcı neyin nereye gittiğini anlamıyor. Bunu düzeltmek için eskiden SPA'ya geçip animasyon kütüphanesi eklemek gerekiyordu. View Transition API ile düz HTML sayfaları arasında bile, birkaç satır CSS ile görselin listeden detay sayfasındaki büyük kapak alanına kayarak taşınmasını sağlayabiliyorsunuz. Bu konuda önce iki sayfalı bir örnekte bunu kuracağız, sonra aynı mantığı JavaScript ile sayfa içindeki bir değişikliğe (yeni kart eklemek) uygulayacağız.
1. Adım: İki Sayfayı Hazırlamak ve Her Birine @view-transition Kuralını Eklemek
Örnekte
from.html (kart listesi) ve to.html (detay) adında iki sayfa var, ikisi de aynı style.css dosyasını kullanıyor. Önemli olan, geçişin iki sayfada da açık olması ve sayfaların aynı origin'de durması. Ortak stil dosyası olduğu için kuralı bir kez yazmanız yeter.CSS:
/* Sayfalar arası geçişi aç: ileri/geri düğmelerinde de çalışır */
@view-transition {
navigation: auto;
}Bu kadarıyla bile sayfalar arasında yumuşak bir çapraz geçiş (cross-fade) görürsünüz. Asıl iş, hangi elemanın hangisine dönüşeceğini tarayıcıya söylemekte.
Sayfaların kökünü ayırt edebilmek için
html etiketlerine kimlik veriyoruz. Birazdan sayfaya özel kurallarda lazım olacak.HTML:
<!-- from.html -->
<html lang="tr" id="from">
<!-- to.html -->
<html lang="tr" id="to">2. Adım: Geçişi DevTools'ta Yavaşlatmak ve Pseudo-element Ağacını Okumak
Animasyonu gözle yakalayamıyorsanız ayar yapamazsınız. Chrome'da DevTools'u açın, sağ üstteki üç nokta menüsünden More tools > Animations panelini getirin ve hızı %10'a çekin. Duraklatıp sayfalar arasında gezinince Elements panelinde
::view-transition katmanını göreceksiniz. İçinde varsayılan ::view-transition-group(root) ve adlandırdığınız her eleman için ayrı bir grup oluşuyor.Bu gruplara CSS ile müdahale edebilirsiniz. Süreyi uzatmak ve kök sayfanın varsayılan geçişini kapatmak için:
CSS:
/* Tüm geçişleri 0.5 saniyeye ayarla */
::view-transition-group(*) {
animation-duration: 0.5s;
}
/* Sadece adlandırılmış elemanlar animasyonlu kalsın */
::view-transition-group(root) {
animation: none;
}Adlandırılmış her grubun içi
Her grubun içinde
::view-transition-image-pair(ad) var, onun da içinde eski ve yeni anlık görüntüyü temsil eden ::view-transition-old(ad) ile ::view-transition-new(ad) duruyor. Sonraki hata ayıklamaların hepsi bu iki parçayı düzeltmekten ibaret.
3. Adım: Başlığı view-transition-name ile İki Sayfa Arasında Taşımak
Eşleştirmek istediğiniz elemana iki sayfada da aynı
view-transition-name değerini veriyorsunuz. Başlıklar iki sayfada da id="title" taşıdığı için tek kural yetiyor:CSS:
#title {
view-transition-name: title;
}
/* Eski başlık, yenisiyle üst üste binmesin */
::view-transition-old(title) {
opacity: 0;
}Dikkat edin: aynı sayfada aynı
view-transition-name değerine sahip iki eleman olursa geçiş iptal olur. İsimler sayfa başına tekil olmalı.4. Adım: Görseli Listeden Kapak Alanına Büyüterek Taşımak ve Bozulmaları Düzeltmek
Görsellerin kimlikleri farklı (
#story-image ve #hero-image) ama ikisine de aynı geçiş adını vererek eşleştirebilirsiniz. Varsayılan hâlde eski ve yeni görüntü üst üste solarak karışıyor, yeni görüntü de gerilip bozuluyor. Çözüm, yerleşik animasyonu kapatıp iki görüntüyü aynı boyuta ve köşe yuvarlaklığına getirmek.CSS:
#story-image,
#hero-image {
view-transition-name: picture;
}
::view-transition-old(picture),
::view-transition-new(picture) {
animation: none;
mix-blend-mode: normal;
height: 100%;
border-radius: 0 0 30px 30px;
}
/* Detay sayfasına giderken yeni görüntü gerilmesin */
#to::view-transition-new(picture) {
object-fit: cover;
overflow: hidden;
}
/* Geri dönerken */
#from::view-transition-new(picture) {
object-fit: contain;
}
#from::view-transition-old(picture) {
object-fit: cover;
overflow: hidden;
border-radius: 20px;
}Burada
#to ve #from seçicileri az önce html etiketine verdiğiniz kimliklerdir. Böylece aynı pseudo-element, hangi sayfadan geldiğine göre farklı davranıyor. Geri dönüş yönünde object-fit değerlerini kendi görselinizin oranına göre denemeniz gerekebilir; bu kısım tamamen gözle ayar.
5. Adım: Karşılığı Olmayan Bir Elemanı (Koyu Katman) Keyframes ile İçeri Almak
Detay sayfasındaki koyu katman ve içindeki yazılar
from.html sayfasında yok, bu yüzden ekrana aniden beliriyor. Katmana #overlay üzerinden bir ad verirseniz, giderken yalnızca ::view-transition-new(overlay), geri dönerken yalnızca ::view-transition-old(overlay) oluşur. Karşılığı olmayan tarafın görüntüsü hiç yaratılmıyor, bu normal.CSS:
#overlay {
view-transition-name: overlay;
}
@keyframes fade-in {
from { opacity: 0; transform: translateY(50px); }
}
@keyframes fade-out {
to { opacity: 0; }
}
/* Görsel yerine oturduktan sonra aşağıdan süzülerek gelsin */
::view-transition-new(overlay) {
animation: 250ms cubic-bezier(0, 0, 0.3, 1) both fade-in;
animation-delay: 0.5s;
}
::view-transition-old(overlay) {
animation: 50ms cubic-bezier(0.3, 0, 1, 1) both fade-out;
}
/* Geçiş sırasında görünen siyah şeridi gizle */
::view-transition-group(overlay) {
overflow: hidden;
}animation-delay: 0.5s değeri, ikinci adımda koyduğunuz 0.5 saniyelik süreye denk geliyor; görsel yerine oturmadan katman gelmesin diye. Süreyi değiştirirseniz gecikmeyi de değiştirin.6. Adım: Sayfa İçi Değişiklikte document.startViewTransition ile Yeni Kart Eklemek
JavaScript ile DOM'a eklenen bir kart CSS tarafından yakalanamaz. Bu durumda değişikliği
document.startViewTransition() içine alıyorsunuz: tarayıcı önce mevcut görüntüyü alıyor, sizin DOM güncellemenizi çalıştırıyor, sonra iki hâl arasını canlandırıyor. Düğme için olay dinleyiciyi addEventListener ile bağlıyoruz.JavaScript:
const dugme = document.querySelector(".new-story-btn");
const kapsayici = document.querySelector(".stories-container");
function kartHazirla(veri) {
const sablon = document.querySelector(".story-card");
if (!sablon) return null;
const kart = sablon.cloneNode(true);
const resim = kart.querySelector("img");
resim.setAttribute("src", veri.image); // src olmalı
resim.removeAttribute("id"); // klonda kimlik çakışmasın
kart.querySelector(".story-tag").textContent = veri.tag;
kart.querySelector(".story-title").textContent = veri.title;
kart.querySelector(".story-description").textContent = veri.description;
return kart;
}
async function kartEkle() {
const kart = kartHazirla({
tag: "Fantasy",
title: "Sky Kingdoms",
description: "Havada süzülen adalar ve onları koruyan kahramanlar.",
image: "./assets/image-5.jpg",
});
if (!kart) return;
// Tarayıcı desteklemiyorsa animasyonsuz ekle
if (!document.startViewTransition) {
kapsayici.appendChild(kart);
return;
}
kart.style.viewTransitionName = "targeted-card";
const gecis = document.startViewTransition(() => {
kapsayici.appendChild(kart);
});
await gecis.finished;
kart.style.viewTransitionName = ""; // adı temizle
}
dugme.addEventListener("click", kartEkle);Önemli satırlar:
setAttribute("src", ) doğru öznitelik; resmi değiştirirken "img" diye bir öznitelik yazmak çalışmaz. Klonlanan kartta id tekrar edeceği için görselin kimliğini kaldırıyoruz, çünkü sayfadaki CSS kuralları kimlikle çalışıyor. viewTransitionName değerini geçiş bitince boşaltmak, kartın sonradan taşınırken istenmeyen animasyon almasını engelliyor.
7. Adım: React ve Next.js'te Deneysel Bayrakları Açmak
React tarafında
ViewTransition bileşeni hâlâ deneysel. Kararlı sürümde yok; react@experimental ve react-dom@experimental paketlerine geçmeniz gerekiyor. Adı sürüme göre unstable_ViewTransition ya da ViewTransition olabilir, kurduğunuz sürümün belgesine bakın.JavaScript:
import { unstable_ViewTransition as ViewTransition } from "react";
export default function Kart() {
return (
<ViewTransition>
<div></div>
</ViewTransition>
);
}Next.js'te ise
next.config.js içinde deneysel bayrağı açıyorsunuz:JavaScript:
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
viewTransition: true,
},
};
module.exports = nextConfig;Bunların ikisi de API'si değişebilen özellikler. Üretim projesinde sürümü sabitleyin.
8. Adım: Canlıya Almadan Önce Kontrol Listesi ve Pratik İpuçları
Destek durumu tarayıcıdan tarayıcıya ve sürümden sürüme değişiyor. Sayfalar arası geçiş Chromium tarafında yerleşik; diğer tarayıcılarda sürüm sürüm ilerliyor. Yayına almadan önce güncel uyumluluk tablosuna bakın. Destek olmayan tarayıcıda CSS kuralı yok sayılır ve sayfa normal şekilde açılır; bozulan bir şey olmaz. JavaScript tarafında ise
document.startViewTransition var mı diye kontrol etmeyi unutmayın.- Hareketi azaltmak isteyen kullanıcılar için geçişi kapatın.
- Aynı sayfada aynı
view-transition-namedeğerini iki elemana vermeyin. - Geçiş süresini kısa tutun; 0.3 ile 0.5 saniye arası çoğu sayfa için yeterli.
- Büyük görsellerde geçiş takılıyorsa görseli önceden yükleyin ve boyutunu optimize edin.
- İki sayfanın aynı origin'de olduğunu ve ikisinde de
@view-transitionkuralının bulunduğunu doğrulayın.
Hareket azaltma tercihi için şu kural yeterli:
CSS:
@media (prefers-reduced-motion: reduce) {
::view-transition-group(*),
::view-transition-old(*),
::view-transition-new(*) {
animation: none;
}
}Kendi sitenizde en çok işe yarayacak yer genellikle liste-detay geçişi; önce başlıkla başlayın, sonra görseli ekleyin. Takıldığınız yerleri ya da farklı tarayıcılarda gördüğünüz tuhaflıkları konunun altına yazabilirsiniz, birlikte bakarız.
Sıkça Sorulan Sorular (SSS)
Soru 1: Paylaşılan CSS örneği canlı (production) ortamda kullanılabilir mi?
Evet. Konudaki kod bloğu bellek güvenliği, hata yakalama ve performans kriterleri gözetilerek hazırlanmıştır; kendi proje mimarinize uyarlayarak doğrudan kullanabilirsiniz.
Soru 2: View Transition API ile Sayfa Geçişlerini Canlandırmak: Tek Satır CSS ile Sayfalar Arası Geçiş ve startViewTransition ile Kart Ekleme uygulamasında en sık yapılan hata nedir?
Girdi doğrulamasını (validation) ve zaman aşımı/kaynak sınırlarını varsayılan değerlerde bırakmaktır. Rehberdeki yapılandırma adımlarını eksiksiz uygulayarak olası darboğazları önleyebilirsiniz.
Evet. Konudaki kod bloğu bellek güvenliği, hata yakalama ve performans kriterleri gözetilerek hazırlanmıştır; kendi proje mimarinize uyarlayarak doğrudan kullanabilirsiniz.
Soru 2: View Transition API ile Sayfa Geçişlerini Canlandırmak: Tek Satır CSS ile Sayfalar Arası Geçiş ve startViewTransition ile Kart Ekleme uygulamasında en sık yapılan hata nedir?
Girdi doğrulamasını (validation) ve zaman aşımı/kaynak sınırlarını varsayılan değerlerde bırakmaktır. Rehberdeki yapılandırma adımlarını eksiksiz uygulayarak olası darboğazları önleyebilirsiniz.

