Magic Flip Cards: การแก้ปัญหาการปรับขนาดทั่วไป
เผยแพร่แล้ว: 2022-03-10โอกาสที่ลูกค้ารายต่อไปของคุณจะใช้คำว่า อินเทอร์แอกทีฟ ขณะแนะนำโครงการของพวกเขาคืออะไร? จากประสบการณ์ของผม คำตอบคือ 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); }
อะไรจะผิดพลาดได้?
โซลูชันมาตรฐานของเรามีปัญหาใหญ่ แต่จะไม่ทำงานเมื่อด้านหน้าด้านหลังต้องการพื้นที่มากกว่าที่ด้านหน้ามีให้ การให้การ์ดมีขนาดใหญ่และขนาดคงที่เป็นวิธีแก้ปัญหา แต่วิธีการดังกล่าวยังรับประกันว่าจะล้มเหลวในบางช่วงสำหรับขนาดหน้าจอบางชุด
องค์ประกอบการออกแบบประกอบด้วยกล่องที่ดูเรียบร้อยพร้อมข้อความที่ลงตัว แต่เมื่อเริ่มต้นการพัฒนา อาจเป็นเรื่องยากที่จะได้เพจและเลย์เอาต์การ์ดที่เหมาะกับเนื้อหาจริง และเมื่อแสดงเนื้อหาแบบไดนามิกจาก CMS ก็เป็นไปไม่ได้! แม้จะมีขีดจำกัดของคำหรืออักขระ ก็มักจะไม่มีวิธีแก้ปัญหาที่น่าเชื่อถือในทุกอุปกรณ์
เราควรพยายามสร้างการใช้งานเลย์เอาต์ที่ทนต่อความยาวของเนื้อหาได้หลากหลาย แต่มันไม่ง่าย! ฉันมักจะมีโอกาสกลับไปใช้ขนาดและตำแหน่งที่แน่นอน ไม่ว่าจะเนื่องมาจากข้อจำกัดด้านเวลา การสนับสนุนเบราว์เซอร์ไม่เพียงพอ การออกแบบอ้างอิงที่อ่อนแอ หรือเพียงแค่ไม่มีประสบการณ์ของฉันเอง
หลายปีที่ผ่านมา ฉันได้เรียนรู้ว่ากระบวนการทำซ้ำที่ดีและบทสนทนาที่ดีกับนักออกแบบสามารถช่วยได้มากเมื่อต้องโต้เถียงกับปัญหาเหล่านี้ และบ่อยครั้งคุณสามารถพบกันที่ไหนสักแห่งที่อยู่ตรงกลางเพื่อให้ได้เลย์เอาต์ที่แข็งแกร่งพร้อมการโต้ตอบ แต่กลับไปที่งานที่ทำอยู่ - สามารถทำได้หรือไม่?
คิดนอกกรอบ
ในความเป็นจริง เป็น ไปได้ที่จะปรับขนาดการ์ดตามเนื้อหาทั้งด้านหน้าและด้านหลัง และไม่ยากอย่างที่คิดในตอนแรก เราแค่ต้องมีระเบียบและสม่ำเสมอ!
การจำกัดปัญหา
เริ่มต้นด้วยการทำรายการข้อกำหนดของเลย์เอาต์ของเรา การพยายามจดสิ่งที่คุณต้องการ อย่างแม่นยำ อาจดูเหมือนเป็นงานที่น่าเบื่อ แต่เป็นวิธีที่ดีในการค้นพบข้อจำกัดที่สามารถทำให้แก้ปัญหาได้ง่ายขึ้น สมมติว่า:
- เราต้องการดูไพ่สี่เหลี่ยมอย่างน้อยหนึ่งใบ จัดเรียงในตารางแบบคอลัมน์เดียวหรือหลายคอลัมน์
- เราต้องการให้การ์ดพลิกบนโฮเวอร์หรือแตะเพื่อแสดงเนื้อหาชุดที่สองที่ด้านหลัง
- เราต้องการให้การ์ดมีขนาดใหญ่พอที่จะแสดงเนื้อหาด้านหน้าและด้านหลังทั้งหมด โดยไม่คำนึงถึงความยาวหรือรูปแบบของเนื้อหา และ
- ในกรณีที่มีหลายคอลัมน์ ตามหลักการแล้ว เราต้องการให้การ์ดทั้งหมดมีขนาดเท่ากัน เพื่อให้แถวเรียงกันอย่างสวยงาม
เมื่อพิจารณาถึงข้อกำหนดเหล่านี้ เราสามารถสังเกตเห็นบางสิ่งที่ทำให้ปัญหาง่ายขึ้น:
- หากจะนำเสนอการ์ดในตาราง เรามีข้อจำกัดด้านความกว้าง นั่นคือ ความกว้างเป็นฟังก์ชันของวิวพอร์ตหรือคอนเทนเนอร์กริด แทนที่จะเป็นเนื้อหาในการ์ดเหล่านั้น
- เนื่องจากเราทราบความกว้างของการ์ด (อย่างน้อยเป็นเปอร์เซ็นต์ของผู้ปกครอง) เราได้แก้ไขสำหรับมิติแนวนอนและเราจำเป็นต้องขยายความสูงของการ์ดเพื่อให้พอดีกับความสูงของด้านหน้าหรือด้านหลัง และ
- หากเราทำได้และการ์ดแต่ละใบมีขนาดเท่ากันในแนวตั้ง เราสามารถใช้
grid-auto-rows
ของ CSS Grid เพื่อสร้างแถวของการ์ดทั้งหมดให้สูงที่สุดเท่าที่การ์ดที่สูงที่สุด
ไขปริศนาไพ่
แล้วเราจะปรับขนาดการ์ดเองได้อย่างไร? ตอนนี้เราได้ลดความซับซ้อนของปัญหาแล้ว และเราอยู่ในแนวทางแก้ไข
ลืมความคิดในการวางเนื้อหาไว้บนเนื้อหาอื่นๆ สักครู่ และมุ่งเน้นไปที่ข้อกำหนดใหม่ของเรา นั่นคือ ผู้ปกครองที่สูงพอๆ กับลูกที่สูงที่สุด ง่ายมาก! การใช้คอลัมน์ทำให้ผู้ปกครองขยายความสูงของลูกที่สูงที่สุดได้ จากนั้น เราต้องใช้มือเพียงเล็กน้อยเพื่อให้เด็กอยู่ในแนวเดียวกัน:
- กำหนดให้ลูกมีความกว้างเท่ากับผู้ปกครอง
- ปล่อยให้ลูกคนที่สองล้นไปทางขวา
- เปลี่ยนซ้ายกลับเข้าที่เดิม
.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); }
หากแนวทางนี้ชัดเจน โปรดมั่นใจได้ว่าฉันใช้เวลาหลายชั่วโมงในการทบทวนความคิดที่แย่จริงๆ บางอย่างก่อนที่จะคิด ตอนแรกฉันวางแผนที่จะพิมพ์ข้อความด้านหลังแบบซ่อนไว้ด้านในด้านหน้าเพื่อขยายการ์ดให้มีขนาดที่ถูกต้อง และเมื่อฉันคิดว่าจะใช้คอลัมน์ล้น เดิมทีฉันครอบตัดคอลัมน์ทางขวาโดยใช้ 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); }
มีข้อควรระวังหรือไม่?
วิธีแก้ปัญหาโดยทั่วไปทำงานได้ดี โดยมีข้อแม้เล็กน้อยที่ต้องคำนึงถึง:
- การ์ดต้องอยู่ในเลย์เอาต์กริดหรือในบริบทอื่นที่ความกว้างไม่ขึ้นกับเนื้อหา
- การ์ดต้องใช้เครื่องห่อเนื้อหาบางประเภท (
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 นี้มีประโยชน์! ทำไมไม่ลองใช้รูปแบบต่างๆ ของแอนิเมชัน เช่น เอฟเฟ็กต์มาตราส่วน หรือภาพซ้อนแบบง่ายๆ เทคนิคนี้ไม่ได้จำกัดอยู่ที่ฟอร์มแฟคเตอร์ของการ์ดเช่นกัน สามารถใช้ได้ทุกที่ที่ความรับผิดชอบในการกำหนดขนาดแนวตั้งตกอยู่กับองค์ประกอบมากกว่าหนึ่งรายการ ลองนึกภาพเว็บไซต์นิตยสารที่มีรูปถ่ายขนาดใหญ่พร้อมคำอธิบายภาพซ้อนทับ คุณสามารถใช้เว็บไซต์นี้เพื่อรองรับทั้งภาพที่มีอัตราส่วนภาพสูงและข้อความไดนามิกขนาดยาว
เหนือสิ่งอื่นใด อย่าลืมประโยชน์ของการใช้เวลาคิดอย่างจริงจังว่ามีวิธีนำการออกแบบที่ดูเหมือนใช้งานได้เฉพาะกับขนาดและตำแหน่งตายตัวหรือไม่ มักจะมีและไม่ว่าปัญหาจะดูยุ่งยากเพียงใดในตอนแรก การเขียนข้อกำหนดทั้งหมดของคุณ การสละเวลาเพื่อสร้างกรณีทดสอบขั้นต่ำ และการก้าวผ่านมันไปอย่างเป็นระบบเป็นทางออกที่ดีที่สุดเสมอ