Magic Flip Cards: การแก้ปัญหาการปรับขนาดทั่วไป

เผยแพร่แล้ว: 2022-03-10
สรุปโดยย่อ ↬ ในบทความนี้ Dan Halliday ทบทวนแนวทางมาตรฐานในการสร้างการ์ดพลิกแบบเคลื่อนไหว และแนะนำวิธีที่ได้รับการปรับปรุงซึ่งแก้ปัญหาเรื่องขนาด

โอกาสที่ลูกค้ารายต่อไปของคุณจะใช้คำว่า อินเทอร์แอกทีฟ ขณะแนะนำโครงการของพวกเขาคืออะไร? จากประสบการณ์ของผม คำตอบคือ 100% ดังนั้นฉันจึงมองหาเทคนิค CSS ที่มีประสิทธิภาพอยู่เสมอ เพื่อช่วยนำเสนอคุณลักษณะและเอฟเฟกต์ต่างๆ ที่เกิดขึ้นเมื่อพูดถึงเป้าหมายนี้

การโต้ตอบเล็กๆ น้อยๆ ที่ฉันขอให้ใช้ครั้งแล้วครั้งเล่าคือการ์ดพลิก — บล็อกของเนื้อหาที่จะเปลี่ยนเมื่อวางเมาส์หรือแตะเพื่อแสดงเนื้อหาที่ด้านหลัง เป็นเอฟเฟกต์เรียบร้อยที่ส่งเสริมการท่องเว็บอย่างสนุกสนาน และอีกวิธีในการแสดงข้อมูลเพิ่มเติมโดยไม่ต้องออกจากเพจ แต่วิธีการมาตรฐานมีปัญหาในการรองรับความยาวของเนื้อหาของการ์ดที่แตกต่างกัน

ในบทช่วยสอนนี้ เราจะสร้างกริดการ์ดแบบพลิกซึ่งแก้ปัญหานั้นได้ด้วยพื้นฐานของ CSS บางอย่าง เช่น การแปลง การยืดหยุ่น และกริด คุณจะต้องทำความคุ้นเคยกับสิ่งเหล่านี้ และจะช่วยให้เข้าใจเทคนิคการจัดตำแหน่ง CSS เป็นอย่างดี เราจะครอบคลุม:

  • วิธีการใช้งานการ์ดพลิกโดยปกติโดยใช้การวางตำแหน่งแบบสัมบูรณ์
  • ปัญหาการปรับขนาดที่การวางตำแหน่งแบบสัมบูรณ์ และ
  • โซลูชันทั่วไปสำหรับการปรับขนาดเนื้อหาที่ซ้อนทับโดยอัตโนมัติ
เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

การสร้างการ์ดพลิกพื้นฐาน

ด้วยการสนับสนุนเบราว์เซอร์ที่ทันสมัยที่ดีสำหรับการแปลงสามมิติ การสร้างการ์ดพลิกขั้นพื้นฐานจึงค่อนข้างตรงไปตรงมา วิธีปกติคือการวางหน้าการ์ดด้านหน้าและด้านหลังไว้ในคอนเทนเนอร์หลัก และจัดตำแหน่งด้านหลังให้พอดีเพื่อให้พอดีกับขนาดของด้านหน้า เพิ่มการแปลงแกน x ไปที่ด้านหลังเพื่อให้ดูเหมือนกลับด้าน เพิ่มรูปแบบอื่นลงในการ์ดเมื่อวางเมาส์ไว้ และเรากำลังทำธุรกิจอยู่

 .cards { display: grid; } .card { perspective: 40rem; } .card-body { transform-style: preserve-3d; transition: var(--time) transform; .card:hover & { transform: rotateX(-180deg); } } .card-front, .card-back { backface-visibility: hidden; } .card-back { position: absolute; top: 0; right: 0; bottom: 0; left: 0; transform: rotateX(-180deg); } 

การใช้งานการ์ดพลิกมาตรฐานโดยใช้การวางตำแหน่งที่แน่นอน (ดูปากกา "[Magic Flip Cards 1: The Standard Implementation](https://codepen.io/smashingmag/pen/JjdPJvo)" โดย Dan Halliday)

การใช้งานการ์ดพลิกมาตรฐานโดยใช้การวางตำแหน่งที่แน่นอน (ดูปากกา “Magic Flip Cards 1: The Standard Implementation” โดย Dan Halliday)

อะไรจะผิดพลาดได้?

โซลูชันมาตรฐานของเรามีปัญหาใหญ่ แต่จะไม่ทำงานเมื่อด้านหน้าด้านหลังต้องการพื้นที่มากกว่าที่ด้านหน้ามีให้ การให้การ์ดมีขนาดใหญ่และขนาดคงที่เป็นวิธีแก้ปัญหา แต่วิธีการดังกล่าวยังรับประกันว่าจะล้มเหลวในบางช่วงสำหรับขนาดหน้าจอบางชุด

วิธีการใช้งานการ์ดพลิกมาตรฐานล้มเหลวด้วยเนื้อหาย้อนหลังที่ยาวขึ้น
นี่คือวิธีที่การใช้งานการ์ดพลิกมาตรฐานล้มเหลวด้วยเนื้อหาย้อนหลังที่ยาวขึ้น (ตัวอย่างขนาดใหญ่)

องค์ประกอบการออกแบบประกอบด้วยกล่องที่ดูเรียบร้อยพร้อมข้อความที่ลงตัว แต่เมื่อเริ่มต้นการพัฒนา อาจเป็นเรื่องยากที่จะได้เพจและเลย์เอาต์การ์ดที่เหมาะกับเนื้อหาจริง และเมื่อแสดงเนื้อหาแบบไดนามิกจาก CMS ก็เป็นไปไม่ได้! แม้จะมีขีดจำกัดของคำหรืออักขระ ก็มักจะไม่มีวิธีแก้ปัญหาที่น่าเชื่อถือในทุกอุปกรณ์

วิธีการใช้การ์ดพลิกมาตรฐานล้มเหลวด้วยเนื้อหาด้านหลังที่ยาวขึ้น (ดูปากกา “[การ์ดพลิกมายากล 2: การวางตำแหน่งที่แน่นอนล้มเหลวอย่างไร] (https://codepen.io/smashingmag/pen/QWbLMLz)” โดย Dan Halliday)

วิธีการใช้การ์ดพลิกมาตรฐานล้มเหลวด้วยเนื้อหาด้านหลังที่ยาวขึ้น (ดูปากกา "การ์ดพลิกมหัศจรรย์ 2: การวางตำแหน่งที่แน่นอนล้มเหลว" โดย Dan Halliday)

เราควรพยายามสร้างการใช้งานเลย์เอาต์ที่ทนต่อความยาวของเนื้อหาได้หลากหลาย แต่มันไม่ง่าย! ฉันมักจะมีโอกาสกลับไปใช้ขนาดและตำแหน่งที่แน่นอน ไม่ว่าจะเนื่องมาจากข้อจำกัดด้านเวลา การสนับสนุนเบราว์เซอร์ไม่เพียงพอ การออกแบบอ้างอิงที่อ่อนแอ หรือเพียงแค่ไม่มีประสบการณ์ของฉันเอง

หลายปีที่ผ่านมา ฉันได้เรียนรู้ว่ากระบวนการทำซ้ำที่ดีและบทสนทนาที่ดีกับนักออกแบบสามารถช่วยได้มากเมื่อต้องโต้เถียงกับปัญหาเหล่านี้ และบ่อยครั้งคุณสามารถพบกันที่ไหนสักแห่งที่อยู่ตรงกลางเพื่อให้ได้เลย์เอาต์ที่แข็งแกร่งพร้อมการโต้ตอบ แต่กลับไปที่งานที่ทำอยู่ - สามารถทำได้หรือไม่?

คิดนอกกรอบ

ในความเป็นจริง เป็น ไปได้ที่จะปรับขนาดการ์ดตามเนื้อหาทั้งด้านหน้าและด้านหลัง และไม่ยากอย่างที่คิดในตอนแรก เราแค่ต้องมีระเบียบและสม่ำเสมอ!

การจำกัดปัญหา

เริ่มต้นด้วยการทำรายการข้อกำหนดของเลย์เอาต์ของเรา การพยายามจดสิ่งที่คุณต้องการ อย่างแม่นยำ อาจดูเหมือนเป็นงานที่น่าเบื่อ แต่เป็นวิธีที่ดีในการค้นพบข้อจำกัดที่สามารถทำให้แก้ปัญหาได้ง่ายขึ้น สมมติว่า:

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

เมื่อพิจารณาถึงข้อกำหนดเหล่านี้ เราสามารถสังเกตเห็นบางสิ่งที่ทำให้ปัญหาง่ายขึ้น:

  • หากจะนำเสนอการ์ดในตาราง เรามีข้อจำกัดด้านความกว้าง นั่นคือ ความกว้างเป็นฟังก์ชันของวิวพอร์ตหรือคอนเทนเนอร์กริด แทนที่จะเป็นเนื้อหาในการ์ดเหล่านั้น
  • เนื่องจากเราทราบความกว้างของการ์ด (อย่างน้อยเป็นเปอร์เซ็นต์ของผู้ปกครอง) เราได้แก้ไขสำหรับมิติแนวนอนและเราจำเป็นต้องขยายความสูงของการ์ดเพื่อให้พอดีกับความสูงของด้านหน้าหรือด้านหลัง และ
  • หากเราทำได้และการ์ดแต่ละใบมีขนาดเท่ากันในแนวตั้ง เราสามารถใช้ grid-auto-rows ของ CSS Grid เพื่อสร้างแถวของการ์ดทั้งหมดให้สูงที่สุดเท่าที่การ์ดที่สูงที่สุด

ไขปริศนาไพ่

แล้วเราจะปรับขนาดการ์ดเองได้อย่างไร? ตอนนี้เราได้ลดความซับซ้อนของปัญหาแล้ว และเราอยู่ในแนวทางแก้ไข

ลืมความคิดในการวางเนื้อหาไว้บนเนื้อหาอื่นๆ สักครู่ และมุ่งเน้นไปที่ข้อกำหนดใหม่ของเรา นั่นคือ ผู้ปกครองที่สูงพอๆ กับลูกที่สูงที่สุด ง่ายมาก! การใช้คอลัมน์ทำให้ผู้ปกครองขยายความสูงของลูกที่สูงที่สุดได้ จากนั้น เราต้องใช้มือเพียงเล็กน้อยเพื่อให้เด็กอยู่ในแนวเดียวกัน:

  1. กำหนดให้ลูกมีความกว้างเท่ากับผู้ปกครอง
  2. ปล่อยให้ลูกคนที่สองล้นไปทางขวา
  3. เปลี่ยนซ้ายกลับเข้าที่เดิม
 .cards { display: grid; } .card-body { display: flex; } .card-front, .card-back { min-width: 100%; mix-blend-mode: multiply; // Preview both faces } .card-back { transform: translate(-100%, 0); } 

การปรับขนาดแนวตั้งโดยการไหลล้นแนวนอนคงที่ (ดูปากกา "[Magic Flip Cards 3: Vertical Sizing by Fixed Horizontal Overflow](https://codepen.io/smashingmag/pen/ExjYvjP)" โดย Dan Halliday)

การปรับขนาดแนวตั้งโดยการไหลล้นแนวนอนคงที่ (ดูปากกา “Magic Flip Cards 3: Vertical Sizing by Fixed Horizontal Overflow” โดย Dan Halliday)

หากแนวทางนี้ชัดเจน โปรดมั่นใจได้ว่าฉันใช้เวลาหลายชั่วโมงในการทบทวนความคิดที่แย่จริงๆ บางอย่างก่อนที่จะคิด ตอนแรกฉันวางแผนที่จะพิมพ์ข้อความด้านหลังแบบซ่อนไว้ด้านในด้านหน้าเพื่อขยายการ์ดให้มีขนาดที่ถูกต้อง และเมื่อฉันคิดว่าจะใช้คอลัมน์ล้น เดิมทีฉันครอบตัดคอลัมน์ทางขวาโดยใช้ overflow:hidden และเปลี่ยนเฉพาะในวินาทีสุดท้ายที่โฮเวอร์เริ่มต้น เนื่องจากฉันยังไม่ทราบว่าฉันสามารถทำให้มันเปลี่ยนได้ จากจุดเริ่มต้นและใช้วิธีอื่นเช่น opacity หรือ backface-visibility เพื่อเปิดและปิดได้ตามต้องการ

กล่าวอีกนัยหนึ่ง วิธีแก้ปัญหาที่ชัดเจนเป็นผลมาจากการทำงานหนัก! หากคุณรู้สึกว่าต้องเอาหัวโขกกับโต๊ะทำงานเป็นเวลาหลายชั่วโมงเกี่ยวกับปัญหาการจัดวาง คุณควรถอยออกมาและตัดสินใจว่าคุณใช้เวลากับลูกค้าอย่างฉลาดหรือไม่: จะแนะนำให้ลูกค้าเปลี่ยนการออกแบบหรือไม่ เพื่อดำเนินการแก้ไขในเวลาของคุณเองเป็นแบบฝึกหัดการเรียนรู้เมื่อความกดดันหมดไป แต่เมื่อคิดวิธีง่ายๆ ออกมาแล้ว อย่ารู้สึกโง่อีกเลย เพราะมันใช้เวลานาน ตอนนี้ มาทบทวนโซลูชันทั้งหมดของเรากัน

 .cards { display: grid; } .card { perspective: 40rem; } .card-body { display: flex; transform-style: preserve-3d; transition: var(--time) transform; .card:hover & { transform: rotateX(-180deg); } } .card-front, .card-back { backface-visibility: hidden; min-width: 100%; } .card-back { transform: rotateX(-180deg) translate(-100%, 0); } 

โซลูชันการ์ดพลิกมายากลแบบสมบูรณ์ (ดูปากกา “[Magic Flip Cards 4: The Complete Solution](https://codepen.io/smashingmag/pen/xxGKLZO)” โดย Dan Halliday)

โซลูชันการ์ดพลิกมายากลที่สมบูรณ์ (ดูปากกา “Magic Flip Cards 4: The Complete Solution” โดย Dan Halliday)

มีข้อควรระวังหรือไม่?

วิธีแก้ปัญหาโดยทั่วไปทำงานได้ดี โดยมีข้อแม้เล็กน้อยที่ต้องคำนึงถึง:

  • การ์ดต้องอยู่ในเลย์เอาต์กริดหรือในบริบทอื่นที่ความกว้างไม่ขึ้นกับเนื้อหา
  • การ์ดต้องใช้เครื่องห่อเนื้อหาบางประเภท ( card-body ของเรา) เพื่อให้พื้นที่วางเมาส์เหนือไม่เปลี่ยนแปลงระหว่างภาพเคลื่อนไหว หากตัวการ์ดเป็นภาพเคลื่อนไหว คุณจะเห็นข้อผิดพลาดบางอย่างเมื่อภาพเคลื่อนไหวหยุดและเริ่มต้นใหม่อย่างรวดเร็ว
  • การใส่สไตล์ เช่น พื้นหลังและเงากล่องควรวางไว้ที่ด้านหน้าและด้านหลังโดยตรง เนื่องจากเอฟเฟกต์ใดๆ บนการ์ดจะไม่เคลื่อนไหว ระวังการจัดสไตล์ เช่น เงากล่องบนตัวการ์ด เพราะจะพลิกกลับด้านโดยธรรมชาติ
  • ด้านหน้าและด้านหลังของการ์ดต้องตั้งค่าคุณสมบัติ box-sizing เป็น border-box หากมีช่องว่างภายในของตัวเอง เนื่องจากความต้องการ min-width ของการ์ด มิฉะนั้น การ์ดจะล้น
  • Safari ยังคงต้องการ -webkit-backface-visibility ในรูปแบบคำนำหน้าผู้ขาย

เพิ่มความโปแลนด์

ตอนนี้ เราได้แก้ไขปัญหาที่ยากแล้ว มาดูการปรับแต่งสองสามอย่างที่เราสามารถทำได้เพื่อให้การโต้ตอบทั้งหมดทำงานได้อย่างราบรื่นที่สุด

ขั้นแรก ตรวจสอบว่าไพ่ทับซ้อนกันขณะพลิกหรือไม่ ขึ้นอยู่กับว่าคุณกำลังใช้หลายคอลัมน์ ความกว้างของรางน้ำของคอลัมน์ การวางแนวของการพลิก และค่า เปอร์ส เปคทีฟของการ์ดหรือไม่ แต่มีแนวโน้มว่าจะเกิดขึ้น คุณสามารถเพิ่มระยะเวลาของแอนิเมชันเพื่อให้มองเห็นสิ่งต่างๆ ได้ชัดเจนขึ้น เมื่อวางเมาส์เหนือ มันดูไม่เป็นธรรมชาติที่การ์ดที่โฮเวอร์จะพลิกไปข้างใต้เพื่อนบ้านในภายหลัง ดังนั้นเราจึงต้องวางมันไว้บนสุดโดยใช้ z-index ง่ายพอ แต่ระวัง! เราต้องรอจนกว่าแอนิเมชั่นขาออกจะเสร็จสมบูรณ์ก่อนที่จะกู้คืน z-index เข้าสู่ transition-delay :

 .card { transition: z-index; transition-delay: var(--time); z-index: 0; &:hover { transition-delay: 0s; z-index: 1; } }

ถัดไป ให้พิจารณาสร้างสถานะ ใช้งาน สำหรับการ์ด ฉันมักจะพยายามสร้างการ์ดเช่นลิงก์เหล่านี้ไปยังที่ที่เกี่ยวข้อง แม้ว่าผู้ออกแบบจะไม่ได้ระบุก็ตาม เนื่องจากองค์ประกอบที่มีเอฟเฟกต์โฮเวอร์แบบนี้ให้ความรู้สึกที่แตะได้จึงเป็นเรื่องดี ดังนั้นจึงเป็นการดีที่จะให้ปลายทางสำหรับผู้อ่านที่ลองเสี่ยงโชค ฉันชอบการแปลงสเกลที่สั้นและละเอียดอ่อน เนื่องจากมันใช้งานได้ดีไม่ว่าครึ่งหลังของแอนิเมชั่นจะถูกตัดออกโดยการโหลดหน้าปลายทางหรือไม่ (ฉันชอบให้เบราว์เซอร์สร้างแอนิเมชั่นบนเครื่องบินให้สมบูรณ์ก่อนการนำทาง ฉันแน่ใจว่ามันจะยากกว่าที่จะนำไปใช้ในทางปฏิบัติมากกว่าเสียง)

นี่เป็นโอกาสที่ดีในการพิจารณาว่าเนื้อหาด้านหลังการ์ดของเราเข้าถึงได้มากเพียงใด มาร์กอัปของเรากระชับและเป็นระเบียบเรียบร้อย เราจึงได้ครอบคลุมถึงโปรแกรมอ่านหน้าจอและกรณีการใช้งานอื่นๆ ที่ไม่สนใจสไตล์ แต่ผู้ใช้คีย์บอร์ดล่ะ หากเราจะทำการ์ดให้เป็นจุดยึด การ์ดเหล่านั้นจะได้รับโฟกัสเป็นแท็บผู้ใช้แป้นพิมพ์ผ่านหน้า มาใช้สถานะโฮเวอร์ของการ์ดเป็นสถานะโฟกัสอีกครั้ง และเนื้อหาด้านหลังจะปรากฏขึ้นอย่างเป็นธรรมชาติในระหว่างการเรียกดูด้วยแป้นพิมพ์

 .card { transition: z-index, transform calc(var(--time) / 4); transition-delay: var(--time), 0s; z-index: 0; &:hover { transition-delay: 0s; z-index: 1; } &:active { transform: scale(0.975); } } .card-body { .card:hover &, .card:focus & { transform: rotateX(-180deg); } }

สุดท้าย อย่าลืมว่าตอนนี้การ์ดจะปรับขนาดให้พอดีกับเนื้อหาโดยอัตโนมัติ คุณสามารถใช้เทคนิคการจัดตำแหน่งและระยะห่างใดก็ได้ที่คุณต้องการภายในคอนเทนเนอร์ด้านหน้าและด้านหลัง ใช้การจัดตำแหน่งแบบยืดหยุ่นเพื่อจัดตำแหน่งชื่อเรื่องให้อยู่ตรงกลาง เพิ่มช่องว่างภายใน หรือแม้แต่ใส่เส้นตารางอื่นในการ์ด นี่คือความสวยงามของโซลูชันเลย์เอาต์ที่ดีซึ่งปรับขนาดตามเนื้อหา — ลดความสัมพันธ์ระหว่างเด็กกับผู้ปกครอง และโมดูลาร์ที่ช่วยให้คุณจดจ่อกับสิ่งใดสิ่งหนึ่งได้ทีละอย่าง

 .card-front, .card-back { display: flex; align-items: center; background-color: white; box-shadow: 0 5px 10px black; border-radius: 0.25rem; padding: 1.5rem; }

ห่อ

ฉันหวังว่าคุณจะพบว่าเทคนิค CSS นี้มีประโยชน์! ทำไมไม่ลองใช้รูปแบบต่างๆ ของแอนิเมชัน เช่น เอฟเฟ็กต์มาตราส่วน หรือภาพซ้อนแบบง่ายๆ เทคนิคนี้ไม่ได้จำกัดอยู่ที่ฟอร์มแฟคเตอร์ของการ์ดเช่นกัน สามารถใช้ได้ทุกที่ที่ความรับผิดชอบในการกำหนดขนาดแนวตั้งตกอยู่กับองค์ประกอบมากกว่าหนึ่งรายการ ลองนึกภาพเว็บไซต์นิตยสารที่มีรูปถ่ายขนาดใหญ่พร้อมคำอธิบายภาพซ้อนทับ คุณสามารถใช้เว็บไซต์นี้เพื่อรองรับทั้งภาพที่มีอัตราส่วนภาพสูงและข้อความไดนามิกขนาดยาว

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