Motion ในการใช้งานจริง: Layout animations และรูปแบบที่รองรับ Accessibility

Framer-motion ได้เปลี่ยนไปแล้ว ตั้งแต่ช่วงปลายปี 2024 แพ็กเกจนี้ถูกเปลี่ยนชื่อเป็น Motion คุณต้องใช้ path การ import เป็น motion/react

บทช่วยสอนส่วนใหญ่นั้นล้าสมัยไปแล้ว เพราะยังคงแสดงการ import แบบเก่าและขาดเรื่อง Accessibility คู่มือนี้จะช่วยให้คุณใช้งาน Motion เวอร์ชันปัจจุบันในโปรเจกต์จริงได้อย่างถูกต้อง

การอัปเกรด

การเปลี่ยนผ่านนั้นง่ายมาก หากคุณใช้เวอร์ชัน 11 การเปลี่ยนเป็นเวอร์ชัน 12 ก็เป็นเพียงแค่การค้นหาและแทนที่ (find-and-replace) เท่านั้น

คุณสามารถรันทั้งสองแพ็กเกจควบคู่กันไปได้ในช่วงการย้าย (migration) แต่อย่าปล่อยให้พวกมันอยู่ใน codebase ของคุณตลอดไป

Layout Animations

prop layout จะบอกให้ Motion คอยเฝ้าดูขนาดและตำแหน่งของ element แทนที่จะปล่อยให้เบราว์เซอร์เปลี่ยนตำแหน่งแบบทันทีทันใด (snap) มันจะทำการสร้าง animation ให้กับการเปลี่ยนแปลงเหล่านั้นแทน

ใช้ layout="position" สำหรับรายการ (lists) วิธีนี้จะช่วยเคลื่อนย้าย element ข้างเคียง (siblings) เมื่อมีไอเทมหนึ่งขยายขนาดขึ้น แต่จะไม่ทำให้เนื้อหาภายในถูกบีบอัด

ใช้ AnimatePresence สำหรับการ mount และ unmount หากไม่มีสิ่งนี้ React จะลบ element ออกจาก DOM ก่อนที่มันจะสามารถทำ animation ขาออก (animate out) ได้

หลีกเลี่ยงการทำ animation กับ height: auto เพราะจะทำให้เกิดอาการภาพกระตุก (visual glitches) แต่ควรใช้ CSS grid wrapper (จาก 0fr เป็น 1fr) เพื่อให้การเปลี่ยนความสูงเป็นไปอย่างราบรื่นแทน

Accessibility

ผู้ใช้ iOS ประมาณ 30% เปิดใช้งาน prefers-reduced-motion อย่าเพียงแค่ปิด animation ทั้งหมด เพราะจะทำให้ layout ของคุณพัง

วิธีที่ผิด: เปลี่ยน <motion.div> เป็น <div> ธรรมดาหากผู้ใช้ต้องการลดการเคลื่อนไหว วิธีนี้จะทำให้ layout เกิดการกระตุก (snap) และดูเหมือนระบบทำงานผิดพลาด

วิธีที่ถูกต้อง: ควบคุมที่ตัว transition ไม่ใช่ที่ตัว component ให้คง <motion.div> ไว้ แต่ตั้งค่า duration เป็น 0 แทน

สร้าง custom hook เพื่อจัดการเรื่องนี้:

วิธีนี้จะช่วยให้มั่นใจว่า element ต่างๆ จะเคลื่อนที่ไปยังตำแหน่งที่ถูกต้องได้โดยไม่มีการเคลื่อนไหวที่รบกวนสายตา

เมื่อไหร่ควรใช้ Motion

ใช้ Web Animations API ของเบราว์เซอร์สำหรับการทำ fade แบบง่ายๆ เพราะไม่มี dependency ใดๆ

ใช้ Motion เมื่อคุณต้องการ:

ที่มา: https://dev.to/bishopz/motion-motionreact-in-production-layout-animations-and-accessible-motion-patterns-16ln