วันนี้เรียนรู้ CSS animations ทำให้ arrow SVG icon bounce ขึ้นลง พร้อมปรับ animation type, timing, duration ด้วย CSS animation properties
ทำไม animation มีประโยชน์?
- Guide users
- Encourage users to take action
- Grab users attention (พอยังมีอยู่)
Requirements
ต้องการ text editor ถ้าไม่มี local dev environment แนะนำ CodePen เริ่ม coding ทันที
เริ่มกันเลย!
HTML: เพิ่ม Container & Arrow
ต้องการ 4 HTML elements:
- Image element สำหรับ arrow icon
- Span element สำหรับ text label เหนือ arrow
- Container-footer element wrap arrow & text label
- Container element wrap ทุก elements
เพิ่ม markup ใน <body></body>:
<div class="container"> <div class="container-footer"> <span class="text-label">Explore</span> <svg class="arrow-circle-down bounce" viewbox="0 0 1792 1792" xmlns="https://www.w3.org/2000/svg"> <path d="M1412 897q0-27-18-45l-91-91q-18-18-45-18t-45 18l-189 189v-502q0-26-19-45t-45-19h-128q-26 0-45 19t-19 45v502l-189-189q-19-19-45-19t-45 19l-91 91q-18 18-18 45t18 45l362 362 91 91q18 18 45 18t45-18l91-91 362-362q18-18 18-45zm252-1q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z" fill="#fff"></path> </svg> </div> </div>
Arrow code เป็น SVG format จาก Font Awesome CSS icon library
เลือก Font Awesome icons ใน SVG format ได้จาก GitHub repo นี้
ประหยัด resources!
เว็บหลายที่ load ทั้ง Font Awesome library แต่ใช้ icons แค่ไม่กี่ตัว — เติม bandwidth ใช้ icons ที่ต้องการจริงใน SVG format ดีกว่า
ตัวอย่างนี้ embed SVG inline ใน HTML เรียกว่า inline SVG มีวิธีอื่นหลายแบบ สำหรับ tutorial อื่น
เปรียบเทียบ original SVG source กับใน markup ข้างต้น จะเห็นผมเปลี่ยน:
- ลบ width/height properties (original ใหญ่เกินไป)
- เพิ่ม class:
arrow-circle-downสำหรับ CSS section
ต่อไปเพิ่ม styling แล้วค่อยมาส่วนสนุก CSS animations!
Styling Container และ Arrow ด้วย CSS
ใน CSS stylesheet เพิ่ม rule-sets นี้:
* { margin: 0; padding: 0; } .container { display: flex; background-color: #26a1ff; height: 100vh; } .container-footer { display: flex; flex-direction: column; align-items: center; margin: auto auto 1rem auto; } .text-label { text-transform: uppercase; font-family: helvetica; font-size: 0.75rem; letter-spacing: 0.2em; color: #fff; } .arrow-circle-down { display: block; width: 40px; height: 40px; margin: 16px 0; }
Refresh browser ควรเห็นแบบนี้:
CSS ทำอะไร:
.containerheight 100vh = เต็ม viewport ทุก devicedisplay: flexทำ flex container ให้ background สีฟ้าอ่อน.arrow-circle-downwidth/height 40px ไม่ใหญ่เกินไป เห็นได้ชัดแต่อย่างพอ.text-labelcosmetic styling uppercase letter-spacing เปลี่ยนตามชอบได้.container-footermargin auto top/right/left บังคับ footer และ children (icon & text) ไปด้านล่าง parent container bottom margin 1rem กันไม่ออก viewport ตอน bounce.container-footerflex properties:flex-direction: columnและalign-items: centerstack text/icon และ center align ใน container footer
margin: auto auto 1rem auto shorthand ของ:
margin-top: auto; margin-right: auto; margin-bottom: 1rem; margin-left: auto;
ต่อไป animate arrow bounce ด้วย CSS!
Animating Scroll Down Arrow ด้วย CSS
animate ได้หลายวิธี CSS, JS, หรือ combo ตัวอย่างนี้ pure CSS
เพิ่ม .bounce class ให้ image element ที่มี SVG arrow แต่ยังไมทำงาน เพราะยังไม่ define/style class ใน CSS
เพิ่มใน CSS stylesheet:
.bounce { animation: bounce 2s; } @keyframes bounce { 0%, 25%, 50%, 75%, 100% { transform: translateY(0); } 40% { transform: translateY(-20px); } 60% { transform: translateY(-12px); } }
ตอนนี้มี bouncing arrow:
CSS Code ทำงานอย่างไร
SVG element มี class .bounce มี property animation
animation property 2 ค่า: bounce และ 2s
bounce= function trigger @keyframe animation@keyframes bounce2s= total duration ของ @keyframe animation
@keyframe animation:
- Duration 2 วินาที (จาก animation property)
- 7 keyframes: 0%, 25%, 40%, 50%, 60%, 75%, 100%
- 3 Y coordinate positions: Y(0), Y(-20px), Y(-12px) กำหนดการเคลื่อนที่ขึ้นลง
Keyframe block แรก: 0%, 25%, 50%, 75%, 100% arrow อยู่ start position Y(0px)
0%, 25%, 50%, 75%, 100% { transform: translateY(0); }
Keyframe block ที่สอง: 40% arrow ขึ้น Y(-20px)
40% { transform: translateY(-20px); }
Keyframe block ที่สาม: 60% arrow ขึ้นอีกครั้ง ครึ่งหนึ่งของครั้งแรก Y(-12px)
60% { transform: translateY(-12px); }
ระหว่าง 40% และ 60% กลับไป Y(0) ที่ 50% ทำให้ arrow ขึ้นลง 2 ครั้ง เร็วๆ
เลือก -12px เพราะ mimic real bouncing ball ครั้งที่ 2 ชนพื้น ขึ้นน้อยกว่าครั้งแรก (ขึ้นอยู่กับน้ำหนัก ความเร็ว วัสดุ ฯลฯ) ให้ wiggle room เพราะไม่มี one way
สับสนลองเล่น duration และ CSS transform translate property practice จะเข้าใจง่ายขึ้น
- ลอง 40% keyframe transform translate -48px ดู
- ลอง animation duration 5 seconds แทน 2 หรือ 100ms (ใช้ milliseconds ได้)
ทดลอง extremes มักได้ "aha" moments
ทดลองดู!
CSS animations มีความเป็นไปได้มากมาย ลอง variations บน animation ที่มีอยู่
Animation-delay Property
ตอนนี้ arrow bounce ทันทีโหลดหน้า อาจอยาก delay เล็กน้อย ไม่ให้ distract users ทันที
เพิ่ม animation-delay ให้ .bounce:
.bounce { animation: bounce 2s; animation-delay: 5s; }
ตอนนี้ animation เริ่มหลังโหลดหน้า 5 วินาที
Animation Iteration Count Property
อยาก repeat animation ใช้ animation-iteration-count:
.bounce { animation: bounce 2s; animation-delay: 5s; animation-iteration-count: 2; }
Arrow เริ่ม bounce หลัง 5 วินาที แตะ repeat keyframe animation อีกรอบ
Infinite CSS Animation
กรณีหายาก อยาก animation รัน infinite เปลี่ยน iteration count เป็น infinite:
.bounce { animation: bounce 2s; animation-iteration-count: infinite; }
แต่ระวัง infinite animations ไม่ควร spin นצח
Exception: living space background พร้อม tiny stars subtle blinking animations อาจ loop เพื่อรักษา atmosphere dynamic
Autoprefixer
เพื่อให้ code ทำงานทุก modern browsers ใช้ autoprefixer ไม่ได้ใส่ใน code ที่นี่เพื่อให้สั้นและอ่านง่าย CodePen มี code ครบรวม prefixed properties
CSS Animation Resources
- MDN Web Docs: CSS Animation