CSS View Transition Generator: สร้าง Page Transition เนียน ๆ โดยไม่ต้องพึ่ง JavaScript Framework
เรียนรู้วิธีใช้ CSS View Transition Generator สร้าง page transition แบบ native ด้วย view-transition-name และ ::view-transition-old/new() pseudo-elements — ไม่ต้องติดตั้ง library เพิ่ม
Table of Contents
ในอดีต page transition ที่เนียนเป็นของเฉพาะ native app หรือเว็บที่ลงทุนกับ JavaScript framework หนัก ๆ พร้อม animation library แถมหากไม่ทำอะไรเลย สิ่งที่ได้คือหน้าจอวาบเป็นสีขาวตอนเปลี่ยนหน้า แต่ตอนนี้ CSS View Transition API เปลี่ยนกติกาแล้ว — transition แบบ morph ระหว่างสองสถานะของหน้าเว็บกลายเป็น platform feature ที่คุมด้วย CSS เกือบทั้งหมด
แต่ปัญหาคือ API ตัวนี้มีศัพท์เทคนิคเยอะ — view-transition-name, ::view-transition-old(), ::view-transition-new(), snapshot group, blend mode — และการพิมพ์ declaration เหล่านี้เองด้วยมือมักผิดพลาดง่าย CSS View Transition Generator แก้ปัญหานี้ตรงจุด: คุณแค่ระบุ transition ที่ต้องการ (ชื่อ, duration, easing, blend mode, direction) เครื่องมือจะสร้าง CSS ที่ copy ไปใช้ได้ทันที พร้อม live preview ให้เห็นการเคลื่อนไหวก่อนเอาไปใช้จริง
ในบทความนี้เราจะพาไปดูว่าเครื่องมือทำอะไรได้บ้าง View Transition API ทำงานอย่างไร และจะเอาไปใช้ในงานจริงได้ทั้ง single-page app และเว็บแบบ multi-page ยังไง
ทำไมต้องใช้ CSS View Transition Generator?
- ไม่ต้องพิมพ์ boilerplate เอง — syntax ของ pseudo-element ตัวนี้ต้องมีทั้ง colon และวงเล็บ พลาดง่ายมาก เครื่องมือสร้าง rule ::view-transition-old/new() ที่ถูกต้องทุกครั้ง ตัดวงลองผิดลองถูกทิ้งไปเลย
- Live preview ระหว่างปรับค่า — อยากลองเปลี่ยน duration จาก 500ms เป็น 350ms หรือเปลี่ยน easing curve แค่ปรับในฟอร์มแล้วดู demo box morph แบบเรียลไทม์ จูน transition แบบนี้ใช้เวลาวินาทีแทนที่จะเป็นนาที
- ใช้ได้ทั้ง SPA และ MPA — ไม่ว่าจะ trigger ด้วย document.startViewTransition() ใน single-page app หรือปล่อยให้ browser จัดการ cross-document navigation ด้วย @view-transition rule CSS ที่สร้างได้ใช้ได้ทั้งสองแบบ — snippet เดียว ใช้ได้สองสถาปัตยกรรม
- มี validation ในตัว — เครื่องมือตรวจว่า view-transition-name ถูกต้อง (ต้องขึ้นต้นด้วยตัวอักษร มีแต่ตัวอักษร ตัวเลข และขีดกลาง) และ duration อยู่ในช่วง 0–60000ms ช่วยดัก error ที่ปกติจะหายเงียบ ๆ ใน production
- ไม่ต้องติดตั้ง dependency ไม่ต้องมี build step — output เป็น CSS ล้วน ๆ วางใน stylesheet, <style> block หรือ CSS-in-JS ก็ได้ ไม่มีอะไรไปตีกับ bundler
- เป็นเหมือนเอกสารสอน API ไปในตัว — ตัวเลือกอย่าง mix-blend-mode และ animation-direction ที่โชว์เป็นฟอร์มทำให้เห็นว่า API ทำอะไรได้จริง นักพัฒนาหลายคนรู้จัก ::view-transition-group() ครั้งแรกจากเครื่องมือแบบนี้
ฟีเจอร์หลัก
| ฟีเจอร์ | ควบคุมอะไร | ค่า default |
|---|---|---|
| view-transition-name | ชื่อที่ใช้จับคู่ snapshot เก่ากับใหม่ | hero-image |
| Duration | ความยาวของ morph เป็น milliseconds (0–60000) | 500ms |
| Timing function | easing curve ของ animation | cubic-bezier(0.4, 0, 0.2, 1) |
| mix-blend-mode | วิธี composite ระหว่าง old/new snapshot ตอน crossfade | normal |
| animation-direction | both, reverse หรือ alternate ของ group | both |
| Style both pseudo-elements | สร้าง rule ทั้ง ::view-transition-old() และ ::view-transition-new() | เปิด |
- Output เรียงตามโครงสร้างของ API จริง — snippet ที่ได้จะขึ้นต้นด้วย declaration .target { view-transition-name: … } ตามด้วย rule ของ pseudo-element และปิดท้ายด้วย block ::view-transition-group() (ถ้าเลือกใช้) — เหมือน mental model ที่คุณใช้อ่าน spec
- Copy, download, clear ครบ — คลิกเดียวเอา CSS ขึ้น clipboard ปุ่ม download บันทึกเป็นไฟล์ และปุ่ม clear รีเซ็ตทุกฟิลด์กลับค่า default
- ได้ shared-element morph ไม่ใช่แค่ crossfade — เพราะ view-transition-name เดียวกันถูก apply กับ element ในทั้งสองสถานะ browser จะ interpolate ทั้งตำแหน่งและขนาดด้วย — เอฟเฟกต์ "morph" ที่ทำให้ transition ดูเหมือน native app
วิธีใช้งาน
- เปิด CSS View Transition Generator แล้วกรอก view-transition-name ของ element ที่ต้องการ animate — เช่น hero-image, product-thumb หรือ article-title
- ตั้งค่า duration — เริ่มที่ 500ms แล้วค่อยปรับ ถ้าเป็น UI เล็ก ๆ ใช้ 200–300ms จะรู้สึก snappy ส่วน hero ขนาดใหญ่ใช้ 500–700ms จะดูมีชั้นเชิงกว่า
- เลือก easing curve — default cubic-bezier(0.4, 0, 0.2, 1) เป็น curve แบบ material ที่ปลอดภัย ลอง ease-in-out หรือ custom cubic-bezier เพื่อเปลี่ยนบุคลิกการเคลื่อนไหว
- ปรับตัวเลือกขั้นสูง (ถ้าต้องการ) — mix-blend-mode สำหรับ crossfade แบบสร้างสรรค์, animation-direction สำหรับกลับทิศ group และ toggle แยกสไตล์ old/new pseudo-element
- Copy CSS ที่สร้างได้ไปใส่ใน project นำ view-transition-name ไปผูกกับ element จริงในทั้งหน้าต้นทางและปลายทาง แล้ว trigger navigation — ดูมัน morph
เข้าใจ View Transition API
เพื่อใช้ CSS ที่ได้อย่างมีประสิทธิภาพ ควรเข้าใจก่อนว่า browser ทำอะไรอยู่เบื้องหลัง ตอน view transition เริ่มทำงาน browser จะจับ snapshot แบบ screenshot ของสถานะเดิม และ live representation ของสถานะใหม่ จากนั้นสร้าง pseudo-element tree ครอบหน้าเว็บไว้ช่วงระยะเวลาหนึ่งของ animation:
- ::view-transition — root overlay ครอบทั้ง viewport
- ::view-transition-group(name) — group box ที่ animate จากตำแหน่ง/ขนาดเดิมไปยังตำแหน่ง/ขนาดใหม่ — ที่นี่แหละที่ morph interpolation เกิดขึ้น
- ::view-transition-old(name) — snapshot นิ่ง ๆ ของ element เดิม จางหายไป
- ::view-transition-new(name) — element ใหม่แบบ live ที่ค่อย ๆ ชัดขึ้น
Output ของ generator จะ target pseudo-element เหล่านี้เป๊ะ ๆ — การตั้ง animation-duration กับ animation-timing-function บน old/new snapshot คุม crossfade ส่วน rule ของ group คุม motion โดยรวม
Same-document vs cross-document — view transition มีสองแบบ:
- Same-document (SPA) transition — ใน single-page app คุณเรียก document.startViewTransition(() => updateTheDOM()) browser จะ snapshot สถานะปัจจุบัน รัน callback เพื่อเปลี่ยน DOM snapshot สถานะใหม่ แล้ว animate ระหว่างสองสถานะ CSS ที่สร้างจากเครื่องมือคุมหน้าตาของ animation นั้น — เป็น approach ที่ app ส่วนใหญ่ของ React/Vue/Svelte ใช้กันทุกวันนี้
- Cross-document (MPA) transition — สำหรับ navigation แบบ multi-page ดั้งเดิม browser รองรับ opt-in transition ระหว่าง full page load ผ่าน rule:
@view-transition {
navigation: auto;
}
พอมี rule นี้ การคลิกลิงก์ไปหน้าอื่นใน site เดียวกันจะ animate จาก document เก่าไปใหม่ — pseudo-element เดิม CSS ชุดเดิม ไม่ต้องเขียน JavaScript เลย
Browser support — ฝั่ง Chromium ส่งมาทั้งสองแบบแล้ว, Safari รองรับ same-document transition ส่วน Firefox กำลัง rollout ทีละส่วน ข่าวดีคือ view transition เป็น enhancement — ถ้า browser ไหนไม่รองรับ navigation ก็แค่เปลี่ยนหน้าแบบไม่มี animation CSS ที่สร้างไว้ degrade เงียบ ๆ ไม่พัง
กฎที่ต้องจำ: view-transition-name ต้อง unique ต่อหน้าหนึ่งสถานะ ถ้ามี element ที่มองเห็นสองตัวใช้ชื่อเดียวกัน transition จะถูกข้ามไปเลย — นี่คือเหตุผลที่ generator ตรวจ format ของชื่อให้ เพราะชื่อพิมพ์ผิดหรือซ้ำคือสาเหตุอันดับหนึ่งที่ view transition "หายเงียบ"
Use Cases ในทางปฏิบัติ
E-commerce product image morph
หน้า grid แสดง thumbnail สินค้า หน้า detail แสดงภาพสินค้าตัวเดิมขนาดใหญ่ ให้ thumbnail มี view-transition-name: product-thumb-42 (unique ต่อสินค้า) และหน้า detail ใส่ชื่อเดียวกันกับ hero image — พอ navigate จาก grid ไป detail thumbnail จะขยายกลายเป็น hero อย่างเนียนตา เอฟเฟกต์ระดับ premium ที่เมื่อก่อนต้องทำ FLIP-style JS measurement เอง ลองตั้ง duration ยาวหน่อย (600–700ms) กับ ease-out curve ให้การขยายจบแบบนุ่ม ๆ
Article hero continuity ใน blog หรือเว็บข่าว
หน้ารายการบทความให้ภาพ featured แต่ละภาพมีชื่ออย่าง article-hero และหน้าบทความใส่ชื่อเดียวกันกับ header image — พอมี @view-transition { navigation: auto; } ใน stylesheet การเปลี่ยนหน้าแบบ MPA ธรรมดาก็ animate hero จาก card ไปเป็น header ได้ โดย static site ที่ไม่มี JavaScript เลย
Dashboard layout changes
Dashboard ต้อง reflow ตลอด — filter ย่อ, panel ขยาย, tab สลับ chart ถ้า wrap การเปลี่ยน state ด้วย document.startViewTransition() และให้แต่ละ panel มี view-transition-name ถาวร panel จะไหลไปตำแหน่งใหม่แทนที่จะ teleport สำหรับ motion ของ panel โดยเฉพาะ ให้จูน rule ::view-transition-group() — ช่อง animation-direction กับ duration ใน generator ป้อนตรงเข้า rule นี้เลย
List-to-detail navigation ใน SPA
pattern คลาสสิกของ mobile — แตะ row ใน list แล้ว row ขยายเป็นหน้า detail — แม็ปเข้า view transition ได้สมบูรณ์ ตั้งชื่อให้แต่ละ row (หรือใช้ชื่อเดียวกัน apply เฉพาะ row ที่ถูกแตะก่อน trigger) แล้วใส่ชื่อเดียวกันที่ detail container crossfade ของ old/new ที่ได้จาก generator บวก size interpolation ของ group จะให้เอฟเฟกต์นี้ด้วย CSS ~10 บรรทัดกับ startViewTransition() หนึ่ง call
Best Practices
- Duration สั้น ๆ ดีที่สุด — UI เล็ก 200–400ms, morph ใหญ่ 400–700ms นานกว่าวินาทีจะรู้สึก lag ไม่ใช่ smooth ไม่ว่า curve จะสวยแค่ไหน
- เคารพ reduced-motion — wrap transition ด้วย @media (prefers-reduced-motion: no-preference) หรือตั้ง ::view-transition-group(*) { animation-duration: 0.01s; } ภายใต้ prefers-reduced-motion: reduce เพื่อให้ user ที่เลือก opt-out ได้หน้าเปลี่ยนทันที
- ใช้ชื่อ unique ต่อ element — ชื่อซ้ำทำให้ transition ถูกข้ามทั้งหมด ถ้าเป็น list ก็ assign item-1, item-2… หรือตั้งชื่อเฉพาะ element ที่ถูก interact
- หนึ่ง hero morph ต่อ navigation พอ — animate ทุก element บนหน้าเปลี่ยนความหรูเป็นสิ่งรบกวน เลือกหนึ่งหรือสอง element ที่ continuity ช่วยจริง — ปกติคือภาพหรือ title ที่ user เพิ่งแตะ
- จับคู่ curve กับ gesture — navigate ไปข้างหน้าด้วย curve แบบ decelerate (ease-out) รู้สึกตอบสนอง ส่วนย้อนกลับใช้ accelerate (ease-in) จะรู้สึกเป็นธรรมชาติ — ช่อง custom cubic-bezier ของ generator ทำได้ทั้งคู่
- ทดสอบ fallback — เปิดหน้าเว็บใน browser ที่ไม่รองรับ View Transition แล้วยืนยันว่าประสบการณ์ยังใช้งานได้ครบ — โดย design แล้วควรเป็นแบบนั้น
เริ่มสร้างได้เลย
Page transition ที่เนียนไม่ใช่สิทธิพิเศษของ framework อีกต่อไป — เป็นแค่ CSS ของ platform ไม่กี่บรรทัด เปิด CSS View Transition Generator ตั้งชื่อ duration และ curve ให้เข้ากับ design system ดู preview สด ๆ แล้ว copy CSS ไปวางใน project ได้เลย — navigation ของคุณจะดู polished ขึ้นเห็นได้ภายในห้านาที
เครื่องมือที่เกี่ยวข้อง:
- CSS Animation Generator — สร้าง animation ด้วย @keyframes พร้อม visual editor สำหรับงานที่ transition ไม่พอ
- CSS Spring Easing Generator — ปรับแต่ง spring curve แบบ physics-based ให้ timing function ดูเป็นธรรมชาติ
- CSS Scroll-Driven Animations Generator — สร้าง scroll-linked animation ด้วย animation-timeline สำหรับเอฟเฟกต์ระหว่าง scroll
ขอให้สนุกกับการ morph!